summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/macos_builds.yml3
-rw-r--r--COPYRIGHT.txt4
-rw-r--r--SConstruct28
-rw-r--r--core/core_bind.cpp10
-rw-r--r--core/crypto/SCsub1
-rw-r--r--core/input/input.cpp33
-rw-r--r--core/input/input.h12
-rw-r--r--core/input/input_enums.h2
-rw-r--r--core/input/input_event.cpp55
-rw-r--r--core/input/input_event.h12
-rw-r--r--core/io/image.h2
-rw-r--r--core/math/a_star.cpp3
-rw-r--r--core/math/a_star.h4
-rw-r--r--core/math/disjoint_set.h4
-rw-r--r--core/math/geometry_3d.cpp29
-rw-r--r--core/object/object.h4
-rw-r--r--core/os/pool_allocator.h3
-rw-r--r--core/templates/hash_map.h4
-rw-r--r--core/templates/set.h3
-rw-r--r--core/templates/vector.h1
-rw-r--r--doc/classes/@GlobalScope.xml7
-rw-r--r--doc/classes/BaseMaterial3D.xml4
-rw-r--r--doc/classes/CanvasItem.xml2
-rw-r--r--doc/classes/CharacterBody2D.xml12
-rw-r--r--doc/classes/CharacterBody3D.xml12
-rw-r--r--doc/classes/Control.xml6
-rw-r--r--doc/classes/EditorNode3DGizmo.xml22
-rw-r--r--doc/classes/EditorNode3DGizmoPlugin.xml29
-rw-r--r--doc/classes/FileDialog.xml2
-rw-r--r--doc/classes/FontData.xml198
-rw-r--r--doc/classes/GraphEdit.xml13
-rw-r--r--doc/classes/Input.xml4
-rw-r--r--doc/classes/InputEventMouseMotion.xml8
-rw-r--r--doc/classes/InputEventScreenDrag.xml4
-rw-r--r--doc/classes/InstancePlaceholder.xml2
-rw-r--r--doc/classes/LineEdit.xml2
-rw-r--r--doc/classes/MeshDataTool.xml4
-rw-r--r--doc/classes/MeshInstance2D.xml2
-rw-r--r--doc/classes/MultiMeshInstance2D.xml2
-rw-r--r--doc/classes/Node.xml1
-rw-r--r--doc/classes/Object.xml1
-rw-r--r--doc/classes/RayCast3D.xml2
-rw-r--r--doc/classes/SpriteBase3D.xml3
-rw-r--r--doc/classes/SpriteFrames.xml4
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--doc/classes/TextServer.xml15
-rw-r--r--doc/classes/TextServerExtension.xml16
-rw-r--r--doc/classes/TextureRect.xml23
-rw-r--r--doc/classes/Tween.xml7
-rw-r--r--doc/classes/Vector2.xml4
-rw-r--r--doc/translations/ar.po568
-rw-r--r--doc/translations/ca.po546
-rw-r--r--doc/translations/classes.pot546
-rw-r--r--doc/translations/cs.po557
-rw-r--r--doc/translations/de.po567
-rw-r--r--doc/translations/el.po554
-rw-r--r--doc/translations/es.po875
-rw-r--r--doc/translations/fa.po559
-rw-r--r--doc/translations/fi.po557
-rw-r--r--doc/translations/fil.po546
-rw-r--r--doc/translations/fr.po585
-rw-r--r--doc/translations/gl.po546
-rw-r--r--doc/translations/hi.po546
-rw-r--r--doc/translations/hu.po546
-rw-r--r--doc/translations/id.po548
-rw-r--r--doc/translations/is.po546
-rw-r--r--doc/translations/it.po559
-rw-r--r--doc/translations/ja.po575
-rw-r--r--doc/translations/ko.po554
-rw-r--r--doc/translations/lv.po546
-rw-r--r--doc/translations/mr.po546
-rw-r--r--doc/translations/nb.po571
-rw-r--r--doc/translations/ne.po546
-rw-r--r--doc/translations/nl.po546
-rw-r--r--doc/translations/pl.po556
-rw-r--r--doc/translations/pt.po564
-rw-r--r--doc/translations/pt_BR.po564
-rw-r--r--doc/translations/ro.po546
-rw-r--r--doc/translations/ru.po574
-rw-r--r--doc/translations/sk.po546
-rw-r--r--doc/translations/sr_Cyrl.po546
-rw-r--r--doc/translations/sv.po546
-rw-r--r--doc/translations/th.po548
-rw-r--r--doc/translations/tl.po548
-rw-r--r--doc/translations/tr.po554
-rw-r--r--doc/translations/uk.po556
-rw-r--r--doc/translations/vi.po554
-rw-r--r--doc/translations/zh_CN.po2261
-rw-r--r--doc/translations/zh_TW.po557
-rw-r--r--drivers/gles3/rasterizer_array.h421
-rw-r--r--drivers/gles3/rasterizer_asserts.h67
-rw-r--r--drivers/gles3/rasterizer_canvas_base_gles3.cpp1354
-rw-r--r--drivers/gles3/rasterizer_canvas_base_gles3.h213
-rw-r--r--drivers/gles3/rasterizer_canvas_batcher.h1560
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp2576
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h252
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp71
-rw-r--r--drivers/gles3/rasterizer_gles3.h10
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h8
-rw-r--r--drivers/gles3/rasterizer_storage_common.h77
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp445
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h197
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1136
-rw-r--r--drivers/gles3/shader_compiler_gles3.h106
-rw-r--r--drivers/gles3/shader_gles3.cpp1406
-rw-r--r--drivers/gles3/shader_gles3.h330
-rw-r--r--drivers/gles3/shaders/SCsub9
-rw-r--r--drivers/gles3/shaders/canvas.glsl1056
-rw-r--r--drivers/gles3/shaders/canvas_shadow.glsl2
-rw-r--r--drivers/gles3/shaders/canvas_uniforms_inc.glsl120
-rw-r--r--drivers/gles3/shaders/copy.glsl41
-rw-r--r--drivers/gles3/shaders/cube_to_dp.glsl4
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl4
-rw-r--r--drivers/gles3/shaders/effect_blur.glsl4
-rw-r--r--drivers/gles3/shaders/lens_distorted.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl32
-rw-r--r--drivers/gles3/shaders/stdlib_inc.glsl58
-rw-r--r--drivers/gles3/shaders/tonemap.glsl4
-rw-r--r--drivers/gles3/texture_loader_gles3.cpp2
-rw-r--r--drivers/gles3/texture_loader_gles3.h5
-rw-r--r--drivers/windows/dir_access_windows.h8
-rw-r--r--editor/action_map_editor.cpp20
-rw-r--r--editor/action_map_editor.h1
-rw-r--r--editor/animation_track_editor_plugins.cpp27
-rw-r--r--editor/connections_dialog.h6
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp8
-rw-r--r--editor/debugger/editor_profiler.cpp2
-rw-r--r--editor/debugger/editor_visual_profiler.cpp2
-rw-r--r--editor/editor_node.cpp9
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_resource_picker.cpp2
-rw-r--r--editor/import/dynamicfont_import_settings.cpp140
-rw-r--r--editor/import/dynamicfont_import_settings.h15
-rw-r--r--editor/import/resource_importer_dynamicfont.cpp3
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp9
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp20
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.cpp1
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp312
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h149
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp29
-rw-r--r--editor/plugins/node_3d_editor_plugin.h13
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp24
-rw-r--r--editor/plugins/path_3d_editor_plugin.h8
-rw-r--r--editor/plugins/shader_editor_plugin.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.h2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp4
-rw-r--r--editor/plugins/texture_region_editor_plugin.h4
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp2
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp68
-rw-r--r--editor/plugins/tiles/tile_atlas_view.h7
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp81
-rw-r--r--editor/project_export.cpp22
-rw-r--r--editor/project_export.h1
-rw-r--r--editor/project_settings_editor.cpp12
-rw-r--r--editor/rename_dialog.h4
-rw-r--r--editor/reparent_dialog.h6
-rw-r--r--editor/shader_globals_editor.cpp1
-rw-r--r--editor/translations/af.po490
-rw-r--r--editor/translations/ar.po549
-rw-r--r--editor/translations/az.po464
-rw-r--r--editor/translations/bg.po496
-rw-r--r--editor/translations/bn.po515
-rw-r--r--editor/translations/br.po452
-rw-r--r--editor/translations/ca.po552
-rw-r--r--editor/translations/cs.po537
-rw-r--r--editor/translations/da.po509
-rw-r--r--editor/translations/de.po649
-rw-r--r--editor/translations/editor.pot447
-rw-r--r--editor/translations/el.po537
-rw-r--r--editor/translations/eo.po516
-rw-r--r--editor/translations/es.po550
-rw-r--r--editor/translations/es_AR.po537
-rw-r--r--editor/translations/et.po493
-rw-r--r--editor/translations/eu.po472
-rw-r--r--editor/translations/fa.po586
-rw-r--r--editor/translations/fi.po644
-rw-r--r--editor/translations/fil.po462
-rw-r--r--editor/translations/fr.po595
-rw-r--r--editor/translations/ga.po459
-rw-r--r--editor/translations/gl.po514
-rw-r--r--editor/translations/he.po522
-rw-r--r--editor/translations/hi.po499
-rw-r--r--editor/translations/hr.po484
-rw-r--r--editor/translations/hu.po514
-rw-r--r--editor/translations/id.po537
-rw-r--r--editor/translations/is.po466
-rw-r--r--editor/translations/it.po539
-rw-r--r--editor/translations/ja.po537
-rw-r--r--editor/translations/ka.po486
-rw-r--r--editor/translations/km.po448
-rw-r--r--editor/translations/ko.po537
-rw-r--r--editor/translations/lt.po483
-rw-r--r--editor/translations/lv.po523
-rw-r--r--editor/translations/mi.po447
-rw-r--r--editor/translations/mk.po450
-rw-r--r--editor/translations/ml.po451
-rw-r--r--editor/translations/mr.po455
-rw-r--r--editor/translations/ms.po1001
-rw-r--r--editor/translations/nb.po1035
-rw-r--r--editor/translations/nl.po539
-rw-r--r--editor/translations/or.po447
-rw-r--r--editor/translations/pl.po547
-rw-r--r--editor/translations/pr.po485
-rw-r--r--editor/translations/pt.po621
-rw-r--r--editor/translations/pt_BR.po537
-rw-r--r--editor/translations/ro.po515
-rw-r--r--editor/translations/ru.po649
-rw-r--r--editor/translations/si.po463
-rw-r--r--editor/translations/sk.po501
-rw-r--r--editor/translations/sl.po511
-rw-r--r--editor/translations/sq.po502
-rw-r--r--editor/translations/sr_Cyrl.po533
-rw-r--r--editor/translations/sr_Latn.po477
-rw-r--r--editor/translations/sv.po514
-rw-r--r--editor/translations/ta.po464
-rw-r--r--editor/translations/te.po456
-rw-r--r--editor/translations/th.po537
-rw-r--r--editor/translations/tl.po503
-rw-r--r--editor/translations/tr.po537
-rw-r--r--editor/translations/tt.po449
-rw-r--r--editor/translations/tzm.po447
-rw-r--r--editor/translations/uk.po646
-rw-r--r--editor/translations/ur_PK.po481
-rw-r--r--editor/translations/vi.po539
-rw-r--r--editor/translations/zh_CN.po706
-rw-r--r--editor/translations/zh_HK.po499
-rw-r--r--editor/translations/zh_TW.po537
-rw-r--r--gles3_builders.py587
-rw-r--r--modules/bullet/area_bullet.cpp4
-rw-r--r--modules/bullet/area_bullet.h10
-rw-r--r--modules/bullet/btRayShape.cpp4
-rw-r--r--modules/bullet/btRayShape.h4
-rw-r--r--modules/bullet/bullet_physics_server.cpp4
-rw-r--r--modules/bullet/bullet_physics_server.h6
-rw-r--r--modules/bullet/bullet_types_converter.cpp4
-rw-r--r--modules/bullet/bullet_types_converter.h7
-rw-r--r--modules/bullet/bullet_utilities.h7
-rw-r--r--modules/bullet/collision_object_bullet.cpp4
-rw-r--r--modules/bullet/collision_object_bullet.h6
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp4
-rw-r--r--modules/bullet/cone_twist_joint_bullet.h7
-rw-r--r--modules/bullet/constraint_bullet.cpp4
-rw-r--r--modules/bullet/constraint_bullet.h7
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp4
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.h6
-rw-r--r--modules/bullet/godot_collision_configuration.cpp4
-rw-r--r--modules/bullet/godot_collision_configuration.h7
-rw-r--r--modules/bullet/godot_collision_dispatcher.cpp4
-rw-r--r--modules/bullet/godot_collision_dispatcher.h9
-rw-r--r--modules/bullet/godot_motion_state.h7
-rw-r--r--modules/bullet/godot_ray_world_algorithm.cpp4
-rw-r--r--modules/bullet/godot_ray_world_algorithm.h4
-rw-r--r--modules/bullet/godot_result_callbacks.cpp5
-rw-r--r--modules/bullet/godot_result_callbacks.h5
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp4
-rw-r--r--modules/bullet/hinge_joint_bullet.h7
-rw-r--r--modules/bullet/joint_bullet.cpp42
-rw-r--r--modules/bullet/joint_bullet.h11
-rw-r--r--modules/bullet/pin_joint_bullet.cpp4
-rw-r--r--modules/bullet/pin_joint_bullet.h7
-rw-r--r--modules/bullet/register_types.cpp4
-rw-r--r--modules/bullet/register_types.h7
-rw-r--r--modules/bullet/rid_bullet.h7
-rw-r--r--modules/bullet/rigid_body_bullet.cpp6
-rw-r--r--modules/bullet/rigid_body_bullet.h10
-rw-r--r--modules/bullet/shape_bullet.cpp4
-rw-r--r--modules/bullet/shape_bullet.h7
-rw-r--r--modules/bullet/shape_owner_bullet.cpp35
-rw-r--r--modules/bullet/shape_owner_bullet.h7
-rw-r--r--modules/bullet/slider_joint_bullet.cpp4
-rw-r--r--modules/bullet/slider_joint_bullet.h7
-rw-r--r--modules/bullet/soft_body_bullet.h4
-rw-r--r--modules/bullet/space_bullet.cpp4
-rw-r--r--modules/bullet/space_bullet.h7
-rw-r--r--modules/csg/csg_gizmos.cpp18
-rw-r--r--modules/csg/csg_gizmos.h8
-rw-r--r--modules/fbx/data/fbx_mesh_data.cpp4
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp43
-rw-r--r--modules/gdscript/gdscript_compiler.cpp86
-rw-r--r--modules/gdscript/gdscript_editor.cpp50
-rw-r--r--modules/gdscript/gdscript_parser.cpp10
-rw-r--r--modules/gdscript/gdscript_parser.h2
-rw-r--r--modules/gdscript/gdscript_vm.cpp7
-rw-r--r--modules/glslang/SCsub9
-rw-r--r--modules/glslang/glslang_resource_limits.h147
-rw-r--r--modules/glslang/register_types.cpp13
-rw-r--r--modules/mbedtls/SCsub6
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h4
-rw-r--r--modules/navigation/godot_navigation_server.cpp4
-rw-r--r--modules/navigation/godot_navigation_server.h4
-rw-r--r--modules/navigation/nav_map.cpp4
-rw-r--r--modules/navigation/nav_map.h5
-rw-r--r--modules/navigation/nav_region.cpp4
-rw-r--r--modules/navigation/nav_region.h5
-rw-r--r--modules/navigation/nav_rid.h4
-rw-r--r--modules/navigation/nav_utils.h4
-rw-r--r--modules/navigation/rvo_agent.cpp4
-rw-r--r--modules/navigation/rvo_agent.h4
-rw-r--r--modules/svg/image_loader_svg.h6
-rw-r--r--modules/text_server_adv/text_server_adv.cpp58
-rw-r--r--modules/text_server_adv/text_server_adv.h5
-rw-r--r--modules/text_server_fb/text_server_fb.cpp24
-rw-r--r--modules/text_server_fb/text_server_fb.h4
-rw-r--r--modules/tga/image_loader_tga.h5
-rw-r--r--modules/visual_script/editor/visual_script_editor.cpp58
-rw-r--r--modules/visual_script/editor/visual_script_editor.h21
-rw-r--r--modules/visual_script/visual_script_expression.cpp2
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp28
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp40
-rw-r--r--modules/visual_script/visual_script_nodes.cpp52
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp16
-rw-r--r--modules/websocket/websocket_server.cpp2
-rw-r--r--modules/webxr/webxr_interface.h2
-rw-r--r--modules/webxr/webxr_interface_js.h2
-rw-r--r--platform/android/export/export_plugin.cpp10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java2
-rw-r--r--platform/javascript/display_server_javascript.cpp2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp4
-rw-r--r--platform/linuxbsd/display_server_x11.h2
-rw-r--r--platform/linuxbsd/gl_manager_x11.h2
-rw-r--r--platform/linuxbsd/joypad_linux.h4
-rw-r--r--platform/osx/display_server_osx.mm3
-rw-r--r--platform/osx/export/export_plugin.cpp64
-rw-r--r--platform/osx/os_osx.mm8
-rw-r--r--platform/windows/display_server_windows.cpp8
-rw-r--r--scene/2d/collision_polygon_2d.cpp16
-rw-r--r--scene/2d/collision_shape_2d.cpp16
-rw-r--r--scene/2d/cpu_particles_2d.cpp34
-rw-r--r--scene/2d/gpu_particles_2d.cpp37
-rw-r--r--scene/2d/polygon_2d.cpp2
-rw-r--r--scene/2d/position_2d.cpp46
-rw-r--r--scene/2d/ray_cast_2d.cpp16
-rw-r--r--scene/2d/shape_cast_2d.cpp16
-rw-r--r--scene/3d/ray_cast_3d.cpp4
-rw-r--r--scene/3d/ray_cast_3d.h4
-rw-r--r--scene/3d/skeleton_ik_3d.cpp4
-rw-r--r--scene/3d/sprite_3d.cpp15
-rw-r--r--scene/3d/sprite_3d.h4
-rw-r--r--scene/3d/xr_nodes.h8
-rw-r--r--scene/animation/tween.cpp25
-rw-r--r--scene/animation/tween.h5
-rw-r--r--scene/gui/button.cpp6
-rw-r--r--scene/gui/check_box.h6
-rw-r--r--scene/gui/check_button.h6
-rw-r--r--scene/gui/graph_edit.cpp60
-rw-r--r--scene/gui/graph_edit.h18
-rw-r--r--scene/gui/graph_node.cpp6
-rw-r--r--scene/gui/label.cpp6
-rw-r--r--scene/gui/line_edit.cpp6
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/link_button.cpp6
-rw-r--r--scene/gui/rich_text_label.cpp9
-rw-r--r--scene/gui/tab_bar.cpp179
-rw-r--r--scene/gui/text_edit.cpp12
-rw-r--r--scene/gui/text_edit.h2
-rw-r--r--scene/gui/texture_rect.cpp22
-rw-r--r--scene/gui/texture_rect.h9
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/gui/view_panner.cpp136
-rw-r--r--scene/gui/view_panner.h (renamed from drivers/gles3/rasterizer_platforms.h)43
-rw-r--r--scene/main/scene_tree.cpp2
-rw-r--r--scene/main/viewport.cpp12
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/font.cpp121
-rw-r--r--scene/resources/font.h3
-rw-r--r--scene/resources/material.h1
-rw-r--r--scene/resources/primitive_meshes.h3
-rw-r--r--scene/resources/separation_ray_shape_2d.cpp16
-rw-r--r--scene/resources/separation_ray_shape_3d.cpp7
-rw-r--r--scene/resources/style_box.cpp23
-rw-r--r--scene/resources/tile_set.cpp94
-rw-r--r--scene/resources/visual_shader.cpp2
-rw-r--r--scene/resources/world_boundary_shape_3d.cpp23
-rw-r--r--servers/audio/effects/eq.h8
-rw-r--r--servers/audio/effects/reverb.h4
-rw-r--r--servers/camera/camera_feed.h4
-rw-r--r--servers/camera_server.h4
-rw-r--r--servers/navigation_server_2d.cpp5
-rw-r--r--servers/navigation_server_2d.h10
-rw-r--r--servers/navigation_server_3d.cpp4
-rw-r--r--servers/navigation_server_3d.h10
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp38
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp18
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp27
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp18
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp14
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h6
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp16
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h10
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h7
-rw-r--r--servers/rendering/renderer_viewport.cpp22
-rw-r--r--servers/rendering/shader_compiler.cpp (renamed from servers/rendering/renderer_rd/shader_compiler_rd.cpp)24
-rw-r--r--servers/rendering/shader_compiler.h (renamed from servers/rendering/renderer_rd/shader_compiler_rd.h)13
-rw-r--r--servers/rendering/shader_language.cpp41
-rw-r--r--servers/rendering_server.cpp3
-rw-r--r--servers/rendering_server.h3
-rw-r--r--servers/text/text_server_extension.cpp15
-rw-r--r--servers/text/text_server_extension.h5
-rw-r--r--servers/text_server.cpp32
-rw-r--r--servers/text_server.h3
-rw-r--r--servers/xr/xr_interface.h4
-rw-r--r--servers/xr/xr_pose.cpp2
-rw-r--r--servers/xr/xr_positional_tracker.h4
-rw-r--r--servers/xr_server.h4
-rw-r--r--thirdparty/README.md17
-rw-r--r--thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp110
-rw-r--r--thirdparty/glslang/StandAlone/DirStackFileIncluder.h149
-rw-r--r--thirdparty/glslang/StandAlone/ResourceLimits.cpp496
-rw-r--r--thirdparty/glslang/StandAlone/ResourceLimits.h57
-rw-r--r--thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp428
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc53
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.hh86
-rw-r--r--thirdparty/harfbuzz/src/hb-config.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-coretext.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-directwrite.cc38
-rw-r--r--thirdparty/harfbuzz/src/hb-fallback-shape.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ft.cc15
-rw-r--r--thirdparty/harfbuzz/src/hb-graphite2.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-iter.hh85
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cmap-table.hh270
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh18
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-face-table-list.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-font.cc20
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-glyf-table.hh73
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh33
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc1
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.hh26
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-math-table.hh10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-metrics.cc7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.cc19
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag-table.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-repacker.hh240
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh55
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.hh1
-rw-r--r--thirdparty/harfbuzz/src/hb-subset.cc18
-rw-r--r--thirdparty/harfbuzz/src/hb-uniscribe.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h6
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aes.h46
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aesni.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/arc4.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/aria.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1.h438
-rw-r--r--thirdparty/mbedtls/include/mbedtls/asn1write.h82
-rw-r--r--thirdparty/mbedtls/include/mbedtls/base64.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bignum.h110
-rw-r--r--thirdparty/mbedtls/include/mbedtls/blowfish.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bn_mul.h57
-rw-r--r--thirdparty/mbedtls/include/mbedtls/camellia.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ccm.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/certs.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/chacha20.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/chachapoly.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/check_config.h209
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cipher.h369
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cipher_internal.h60
-rw-r--r--thirdparty/mbedtls/include/mbedtls/cmac.h51
-rw-r--r--thirdparty/mbedtls/include/mbedtls/compat-1.3.h37
-rw-r--r--thirdparty/mbedtls/include/mbedtls/config.h826
-rw-r--r--thirdparty/mbedtls/include/mbedtls/constant_time.h45
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ctr_drbg.h213
-rw-r--r--thirdparty/mbedtls/include/mbedtls/debug.h87
-rw-r--r--thirdparty/mbedtls/include/mbedtls/des.h45
-rw-r--r--thirdparty/mbedtls/include/mbedtls/dhm.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdh.h63
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecdsa.h97
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecjpake.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp.h183
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ecp_internal.h39
-rw-r--r--thirdparty/mbedtls/include/mbedtls/entropy.h39
-rw-r--r--thirdparty/mbedtls/include/mbedtls/entropy_poll.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/error.h130
-rw-r--r--thirdparty/mbedtls/include/mbedtls/gcm.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/havege.h38
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hkdf.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/hmac_drbg.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md.h51
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md2.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md4.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md5.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/md_internal.h70
-rw-r--r--thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/net.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/net_sockets.h40
-rw-r--r--thirdparty/mbedtls/include/mbedtls/nist_kw.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/oid.h97
-rw-r--r--thirdparty/mbedtls/include/mbedtls/padlock.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pem.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pk.h198
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pk_internal.h37
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs11.h154
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs12.h37
-rw-r--r--thirdparty/mbedtls/include/mbedtls/pkcs5.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform.h89
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_time.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/platform_util.h122
-rw-r--r--thirdparty/mbedtls/include/mbedtls/poly1305.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ripemd160.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/rsa.h147
-rw-r--r--thirdparty/mbedtls/include/mbedtls/rsa_internal.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha1.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha256.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/sha512.h49
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl.h1515
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cache.h38
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h99
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_cookie.h35
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_internal.h813
-rw-r--r--thirdparty/mbedtls/include/mbedtls/ssl_ticket.h37
-rw-r--r--thirdparty/mbedtls/include/mbedtls/threading.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/timing.h31
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h41
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509.h95
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crl.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_crt.h447
-rw-r--r--thirdparty/mbedtls/include/mbedtls/x509_csr.h33
-rw-r--r--thirdparty/mbedtls/include/mbedtls/xtea.h31
-rw-r--r--thirdparty/mbedtls/library/aes.c352
-rw-r--r--thirdparty/mbedtls/library/aesni.c35
-rw-r--r--thirdparty/mbedtls/library/arc4.c35
-rw-r--r--thirdparty/mbedtls/library/aria.c125
-rw-r--r--thirdparty/mbedtls/library/asn1parse.c243
-rw-r--r--thirdparty/mbedtls/library/asn1write.c166
-rw-r--r--thirdparty/mbedtls/library/base64.c123
-rw-r--r--thirdparty/mbedtls/library/bignum.c790
-rw-r--r--thirdparty/mbedtls/library/blowfish.c74
-rw-r--r--thirdparty/mbedtls/library/camellia.c96
-rw-r--r--thirdparty/mbedtls/library/ccm.c98
-rw-r--r--thirdparty/mbedtls/library/certs.c594
-rw-r--r--thirdparty/mbedtls/library/chacha20.c77
-rw-r--r--thirdparty/mbedtls/library/chachapoly.c71
-rw-r--r--thirdparty/mbedtls/library/check_crypto_config.h91
-rw-r--r--thirdparty/mbedtls/library/cipher.c625
-rw-r--r--thirdparty/mbedtls/library/cipher_wrap.c179
-rw-r--r--thirdparty/mbedtls/library/cmac.c94
-rw-r--r--thirdparty/mbedtls/library/common.h305
-rw-r--r--thirdparty/mbedtls/library/constant_time.c819
-rw-r--r--thirdparty/mbedtls/library/constant_time_internal.h329
-rw-r--r--thirdparty/mbedtls/library/constant_time_invasive.h51
-rw-r--r--thirdparty/mbedtls/library/ctr_drbg.c444
-rw-r--r--thirdparty/mbedtls/library/debug.c57
-rw-r--r--thirdparty/mbedtls/library/des.c112
-rw-r--r--thirdparty/mbedtls/library/dhm.c93
-rw-r--r--thirdparty/mbedtls/library/ecdh.c116
-rw-r--r--thirdparty/mbedtls/library/ecdsa.c80
-rw-r--r--thirdparty/mbedtls/library/ecjpake.c83
-rw-r--r--thirdparty/mbedtls/library/ecp.c1307
-rw-r--r--thirdparty/mbedtls/library/ecp_curves.c136
-rw-r--r--thirdparty/mbedtls/library/ecp_invasive.h81
-rw-r--r--thirdparty/mbedtls/library/entropy.c60
-rw-r--r--thirdparty/mbedtls/library/entropy_poll.c108
-rw-r--r--thirdparty/mbedtls/library/error.c1194
-rw-r--r--thirdparty/mbedtls/library/gcm.c256
-rw-r--r--thirdparty/mbedtls/library/havege.c73
-rw-r--r--thirdparty/mbedtls/library/hkdf.c44
-rw-r--r--thirdparty/mbedtls/library/hmac_drbg.c50
-rw-r--r--thirdparty/mbedtls/library/md.c532
-rw-r--r--thirdparty/mbedtls/library/md2.c42
-rw-r--r--thirdparty/mbedtls/library/md4.c109
-rw-r--r--thirdparty/mbedtls/library/md5.c109
-rw-r--r--thirdparty/mbedtls/library/md_wrap.c611
-rw-r--r--thirdparty/mbedtls/library/memory_buffer_alloc.c35
-rw-r--r--thirdparty/mbedtls/library/mps_common.h195
-rw-r--r--thirdparty/mbedtls/library/mps_error.h103
-rw-r--r--thirdparty/mbedtls/library/mps_reader.c564
-rw-r--r--thirdparty/mbedtls/library/mps_reader.h382
-rw-r--r--thirdparty/mbedtls/library/mps_trace.c127
-rw-r--r--thirdparty/mbedtls/library/mps_trace.h175
-rw-r--r--thirdparty/mbedtls/library/net_sockets.c76
-rw-r--r--thirdparty/mbedtls/library/nist_kw.c87
-rw-r--r--thirdparty/mbedtls/library/oid.c98
-rw-r--r--thirdparty/mbedtls/library/padlock.c39
-rw-r--r--thirdparty/mbedtls/library/pem.c50
-rw-r--r--thirdparty/mbedtls/library/pk.c146
-rw-r--r--thirdparty/mbedtls/library/pk_wrap.c407
-rw-r--r--thirdparty/mbedtls/library/pkcs11.c29
-rw-r--r--thirdparty/mbedtls/library/pkcs12.c62
-rw-r--r--thirdparty/mbedtls/library/pkcs5.c113
-rw-r--r--thirdparty/mbedtls/library/pkparse.c177
-rw-r--r--thirdparty/mbedtls/library/pkwrite.c132
-rw-r--r--thirdparty/mbedtls/library/platform.c111
-rw-r--r--thirdparty/mbedtls/library/platform_util.c35
-rw-r--r--thirdparty/mbedtls/library/poly1305.c94
-rw-r--r--thirdparty/mbedtls/library/ripemd160.c111
-rw-r--r--thirdparty/mbedtls/library/rsa.c438
-rw-r--r--thirdparty/mbedtls/library/rsa_internal.c35
-rw-r--r--thirdparty/mbedtls/library/sha1.c111
-rw-r--r--thirdparty/mbedtls/library/sha256.c89
-rw-r--r--thirdparty/mbedtls/library/sha512.c214
-rw-r--r--thirdparty/mbedtls/library/ssl_cache.c107
-rw-r--r--thirdparty/mbedtls/library/ssl_ciphersuites.c210
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c1169
-rw-r--r--thirdparty/mbedtls/library/ssl_cookie.c62
-rw-r--r--thirdparty/mbedtls/library/ssl_msg.c5922
-rw-r--r--thirdparty/mbedtls/library/ssl_srv.c949
-rw-r--r--thirdparty/mbedtls/library/ssl_ticket.c210
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c9240
-rw-r--r--thirdparty/mbedtls/library/ssl_tls13_keys.c349
-rw-r--r--thirdparty/mbedtls/library/ssl_tls13_keys.h274
-rw-r--r--thirdparty/mbedtls/library/threading.c39
-rw-r--r--thirdparty/mbedtls/library/timing.c37
-rw-r--r--thirdparty/mbedtls/library/version.c35
-rw-r--r--thirdparty/mbedtls/library/version_features.c132
-rw-r--r--thirdparty/mbedtls/library/x509.c198
-rw-r--r--thirdparty/mbedtls/library/x509_create.c46
-rw-r--r--thirdparty/mbedtls/library/x509_crl.c112
-rw-r--r--thirdparty/mbedtls/library/x509_crt.c1043
-rw-r--r--thirdparty/mbedtls/library/x509_csr.c62
-rw-r--r--thirdparty/mbedtls/library/x509write_crt.c108
-rw-r--r--thirdparty/mbedtls/library/x509write_csr.c126
-rw-r--r--thirdparty/mbedtls/library/xtea.c68
-rw-r--r--thirdparty/mbedtls/patches/padlock.diff13
627 files changed, 85355 insertions, 38780 deletions
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index dec3abe52b..aede3f8d49 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -3,7 +3,8 @@ on: [push, pull_request]
# Global Settings
env:
- GODOT_BASE_BRANCH: master
+ # Only used for the cache key. Increment version to force clean build.
+ GODOT_BASE_BRANCH: master-v2
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes
concurrency:
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index b649a36de3..eb5f619b87 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -206,11 +206,11 @@ Copyright: 2010-2020, Google, Inc.
2019-2020, Facebook, Inc.
2012, Mozilla Foundation
2011, Codethink Limited
- 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
+ 2008, 2010, Nokia Corporation and/or its subsidiary(-ies)
2009, Keith Stribley
2009, Martin Hosken and SIL International
2007, Chris Wilson
- 2006, Behdad Esfahbod
+ 2005-2006, 2020-2021, Behdad Esfahbod
2005, David Turner
2004, 2007-2010, Red Hat, Inc.
1998-2004, David Turner and Werner Lemberg
diff --git a/SConstruct b/SConstruct
index bdf4937cd7..03b409e09b 100644
--- a/SConstruct
+++ b/SConstruct
@@ -11,6 +11,31 @@ import pickle
import sys
import time
from collections import OrderedDict
+from importlib.util import spec_from_file_location, module_from_spec
+
+# Explicitly resolve the helper modules, this is done to avoid clash with
+# modules of the same name that might be randomly added (e.g. someone adding
+# an `editor.py` file at the root of the module creates a clash with the editor
+# folder when doing `import editor.template_builder`)
+
+
+def _helper_module(name, path):
+ spec = spec_from_file_location(name, path)
+ module = module_from_spec(spec)
+ spec.loader.exec_module(module)
+ sys.modules[name] = module
+
+
+_helper_module("gles3_builders", "gles3_builders.py")
+_helper_module("glsl_builders", "glsl_builders.py")
+_helper_module("methods", "methods.py")
+_helper_module("platform_methods", "platform_methods.py")
+_helper_module("version", "version.py")
+_helper_module("core.core_builders", "core/core_builders.py")
+_helper_module("editor.editor_builders", "editor/editor_builders.py")
+_helper_module("editor.template_builders", "editor/template_builders.py")
+_helper_module("main.main_builders", "main/main_builders.py")
+_helper_module("modules.modules_builders", "modules/modules_builders.py")
# Local
import methods
@@ -576,7 +601,8 @@ if selected_platform in platform_list:
if env["target"] == "release":
if env["tools"]:
- print("Error: The editor can only be built with `target=debug` or `target=release_debug`.")
+ print("ERROR: The editor can only be built with `target=debug` or `target=release_debug`.")
+ print(" Use `tools=no target=release` to build a release export template.")
Exit(255)
suffix += ".opt"
env.Append(CPPDEFINES=["NDEBUG"])
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 1891ea7e3a..ef28f43f05 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -698,10 +698,7 @@ Variant Geometry2D::line_intersects_line(const Vector2 &p_from_a, const Vector2
Vector<Vector2> Geometry2D::get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) {
Vector2 r1, r2;
::Geometry2D::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2);
- Vector<Vector2> r;
- r.resize(2);
- r.set(0, r1);
- r.set(1, r2);
+ Vector<Vector2> r = { r1, r2 };
return r;
}
@@ -923,10 +920,7 @@ Vector<Plane> Geometry3D::build_capsule_planes(float p_radius, float p_height, i
Vector<Vector3> Geometry3D::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) {
Vector3 r1, r2;
::Geometry3D::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2);
- Vector<Vector3> r;
- r.resize(2);
- r.set(0, r1);
- r.set(1, r2);
+ Vector<Vector3> r = { r1, r2 };
return r;
}
diff --git a/core/crypto/SCsub b/core/crypto/SCsub
index 4f3104d84b..1fe2fa5b23 100644
--- a/core/crypto/SCsub
+++ b/core/crypto/SCsub
@@ -30,6 +30,7 @@ if not has_module:
thirdparty_mbedtls_sources = [
"aes.c",
"base64.c",
+ "constant_time.c",
"md5.c",
"sha1.c",
"sha256.c",
diff --git a/core/input/input.cpp b/core/input/input.cpp
index c5540f926d..26df16792d 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -121,7 +121,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_accelerometer", "value"), &Input::set_accelerometer);
ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
- ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed);
+ ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
@@ -183,7 +183,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
}
}
-void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
+void Input::VelocityTrack::update(const Vector2 &p_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
uint32_t tdiff = tick - last_tick;
float delta_t = tdiff / 1000000.0;
@@ -202,17 +202,17 @@ void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
accum = accum - slice;
accum_t -= min_ref_frame;
- speed = (slice / min_ref_frame).lerp(speed, min_ref_frame / max_ref_frame);
+ velocity = (slice / min_ref_frame).lerp(velocity, min_ref_frame / max_ref_frame);
}
}
-void Input::SpeedTrack::reset() {
+void Input::VelocityTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
- speed = Vector2();
+ velocity = Vector2();
accum_t = 0;
}
-Input::SpeedTrack::SpeedTrack() {
+Input::VelocityTrack::VelocityTrack() {
min_ref_frame = 0.1;
max_ref_frame = 0.3;
reset();
@@ -515,7 +515,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
drag_event->set_position(mm->get_position());
drag_event->set_relative(mm->get_relative());
- drag_event->set_speed(mm->get_speed());
+ drag_event->set_velocity(mm->get_velocity());
event_dispatch_function(drag_event);
}
@@ -525,12 +525,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
if (st.is_valid()) {
if (st->is_pressed()) {
- SpeedTrack &track = touch_speed_track[st->get_index()];
+ VelocityTrack &track = touch_velocity_track[st->get_index()];
track.reset();
} else {
// Since a pointer index may not occur again (OSs may or may not reuse them),
// imperatively remove it from the map to keep no fossil entries in it
- touch_speed_track.erase(st->get_index());
+ touch_velocity_track.erase(st->get_index());
}
if (emulate_mouse_from_touch) {
@@ -570,9 +570,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
Ref<InputEventScreenDrag> sd = p_event;
if (sd.is_valid()) {
- SpeedTrack &track = touch_speed_track[sd->get_index()];
+ VelocityTrack &track = touch_velocity_track[sd->get_index()];
track.update(sd->get_relative());
- sd->set_speed(track.speed);
+ sd->set_velocity(track.velocity);
if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
Ref<InputEventMouseMotion> motion_event;
@@ -582,7 +582,7 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
motion_event->set_position(sd->get_position());
motion_event->set_global_position(sd->get_position());
motion_event->set_relative(sd->get_relative());
- motion_event->set_speed(sd->get_speed());
+ motion_event->set_velocity(sd->get_velocity());
motion_event->set_button_mask(mouse_button_mask);
_parse_input_event_impl(motion_event, true);
@@ -696,7 +696,7 @@ void Input::set_gyroscope(const Vector3 &p_gyroscope) {
}
void Input::set_mouse_position(const Point2 &p_posf) {
- mouse_speed_track.update(p_posf - mouse_pos);
+ mouse_velocity_track.update(p_posf - mouse_pos);
mouse_pos = p_posf;
}
@@ -704,8 +704,8 @@ Point2 Input::get_mouse_position() const {
return mouse_pos;
}
-Point2 Input::get_last_mouse_speed() const {
- return mouse_speed_track.speed;
+Point2 Input::get_last_mouse_velocity() const {
+ return mouse_velocity_track.velocity;
}
MouseButton Input::get_mouse_button_mask() const {
@@ -892,7 +892,8 @@ void Input::set_event_dispatch_function(EventDispatchFunc p_function) {
void Input::joy_button(int p_device, JoyButton p_button, bool p_pressed) {
_THREAD_SAFE_METHOD_;
Joypad &joy = joy_names[p_device];
- //printf("got button %i, mapping is %i\n", p_button, joy.mapping);
+ ERR_FAIL_INDEX((int)p_button, (int)JoyButton::MAX);
+
if (joy.last_buttons[(size_t)p_button] == p_pressed) {
return;
}
diff --git a/core/input/input.h b/core/input/input.h
index b723fb563a..8b1d7d6161 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -117,9 +117,9 @@ private:
int mouse_from_touch_index = -1;
- struct SpeedTrack {
+ struct VelocityTrack {
uint64_t last_tick;
- Vector2 speed;
+ Vector2 velocity;
Vector2 accum;
float accum_t;
float min_ref_frame;
@@ -127,7 +127,7 @@ private:
void update(const Vector2 &p_delta_p);
void reset();
- SpeedTrack();
+ VelocityTrack();
};
struct Joypad {
@@ -141,8 +141,8 @@ private:
int hat_current = 0;
};
- SpeedTrack mouse_speed_track;
- Map<int, SpeedTrack> touch_speed_track;
+ VelocityTrack mouse_velocity_track;
+ Map<int, VelocityTrack> touch_velocity_track;
Map<int, Joypad> joy_names;
int fallback_mapping = -1;
@@ -274,7 +274,7 @@ public:
Vector3 get_gyroscope() const;
Point2 get_mouse_position() const;
- Point2 get_last_mouse_speed() const;
+ Vector2 get_last_mouse_velocity() const;
MouseButton get_mouse_button_mask() const;
void warp_mouse_position(const Vector2 &p_to);
diff --git a/core/input/input_enums.h b/core/input/input_enums.h
index aa55316ec8..0282de2176 100644
--- a/core/input/input_enums.h
+++ b/core/input/input_enums.h
@@ -83,7 +83,7 @@ enum class JoyButton {
PADDLE4 = 19,
TOUCHPAD = 20,
SDL_MAX = 21,
- MAX = 36, // Android supports up to 36 buttons.
+ MAX = 128, // Android supports up to 36 buttons. DirectInput supports up to 128 buttons.
};
enum class MIDIMessage {
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 794ed0275d..c608076a21 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -739,20 +739,15 @@ Vector2 InputEventMouseMotion::get_relative() const {
return relative;
}
-void InputEventMouseMotion::set_speed(const Vector2 &p_speed) {
- speed = p_speed;
+void InputEventMouseMotion::set_velocity(const Vector2 &p_velocity) {
+ velocity = p_velocity;
}
-Vector2 InputEventMouseMotion::get_speed() const {
- return speed;
+Vector2 InputEventMouseMotion::get_velocity() const {
+ return velocity;
}
Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
- Vector2 g = get_global_position();
- Vector2 l = p_xform.xform(get_position() + p_local_ofs);
- Vector2 r = p_xform.basis_xform(get_relative());
- Vector2 s = p_xform.basis_xform(get_speed());
-
Ref<InputEventMouseMotion> mm;
mm.instantiate();
@@ -761,20 +756,20 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
mm->set_modifiers_from_event(this);
- mm->set_position(l);
+ mm->set_position(p_xform.xform(get_position() + p_local_ofs));
mm->set_pressure(get_pressure());
mm->set_tilt(get_tilt());
- mm->set_global_position(g);
+ mm->set_global_position(get_global_position());
mm->set_button_mask(get_button_mask());
- mm->set_relative(r);
- mm->set_speed(s);
+ mm->set_relative(p_xform.basis_xform(get_relative()));
+ mm->set_velocity(p_xform.basis_xform(get_velocity()));
return mm;
}
String InputEventMouseMotion::as_text() const {
- return vformat(RTR("Mouse motion at position (%s) with speed (%s)"), String(get_position()), String(get_speed()));
+ return vformat(RTR("Mouse motion at position (%s) with velocity (%s)"), String(get_position()), String(get_velocity()));
}
String InputEventMouseMotion::to_string() {
@@ -802,7 +797,7 @@ String InputEventMouseMotion::to_string() {
// Work around the fact vformat can only take 5 substitutions but 6 need to be passed.
String mask_and_position = vformat("button_mask=%s, position=(%s)", button_mask_string, String(get_position()));
- return vformat("InputEventMouseMotion: %s, relative=(%s), speed=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_speed()), get_pressure(), String(get_tilt()));
+ return vformat("InputEventMouseMotion: %s, relative=(%s), velocity=(%s), pressure=%.2f, tilt=(%s)", mask_and_position, String(get_relative()), String(get_velocity()), get_pressure(), String(get_tilt()));
}
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
@@ -841,7 +836,7 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
set_position(motion->get_position());
set_global_position(motion->get_global_position());
- set_speed(motion->get_speed());
+ set_velocity(motion->get_velocity());
relative += motion->get_relative();
return true;
@@ -857,13 +852,13 @@ void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
- ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed);
- ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed);
+ ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMouseMotion::set_velocity);
+ ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMouseMotion::get_velocity);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity"), "set_velocity", "get_velocity");
}
///////////////////////////////////
@@ -1188,12 +1183,12 @@ Vector2 InputEventScreenDrag::get_relative() const {
return relative;
}
-void InputEventScreenDrag::set_speed(const Vector2 &p_speed) {
- speed = p_speed;
+void InputEventScreenDrag::set_velocity(const Vector2 &p_velocity) {
+ velocity = p_velocity;
}
-Vector2 InputEventScreenDrag::get_speed() const {
- return speed;
+Vector2 InputEventScreenDrag::get_velocity() const {
+ return velocity;
}
Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
@@ -1207,17 +1202,17 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con
sd->set_index(index);
sd->set_position(p_xform.xform(pos + p_local_ofs));
sd->set_relative(p_xform.basis_xform(relative));
- sd->set_speed(p_xform.basis_xform(speed));
+ sd->set_velocity(p_xform.basis_xform(velocity));
return sd;
}
String InputEventScreenDrag::as_text() const {
- return vformat(RTR("Screen dragged with %s touch points at position (%s) with speed of (%s)"), itos(index), String(get_position()), String(get_speed()));
+ return vformat(RTR("Screen dragged with %s touch points at position (%s) with velocity of (%s)"), itos(index), String(get_position()), String(get_velocity()));
}
String InputEventScreenDrag::to_string() {
- return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), speed=(%s)", index, String(get_position()), String(get_relative()), String(get_speed()));
+ return vformat("InputEventScreenDrag: index=%d, position=(%s), relative=(%s), velocity=(%s)", index, String(get_position()), String(get_relative()), String(get_velocity()));
}
bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) {
@@ -1230,7 +1225,7 @@ bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) {
}
set_position(drag->get_position());
- set_speed(drag->get_speed());
+ set_velocity(drag->get_velocity());
relative += drag->get_relative();
return true;
@@ -1246,13 +1241,13 @@ void InputEventScreenDrag::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative);
ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative);
- ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventScreenDrag::set_speed);
- ClassDB::bind_method(D_METHOD("get_speed"), &InputEventScreenDrag::get_speed);
+ ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventScreenDrag::set_velocity);
+ ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventScreenDrag::get_velocity);
ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity"), "set_velocity", "get_velocity");
}
///////////////////////////////////
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 184d883af8..29450dfc52 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -271,7 +271,7 @@ class InputEventMouseMotion : public InputEventMouse {
Vector2 tilt;
float pressure = 0;
Vector2 relative;
- Vector2 speed;
+ Vector2 velocity;
protected:
static void _bind_methods();
@@ -286,8 +286,8 @@ public:
void set_relative(const Vector2 &p_relative);
Vector2 get_relative() const;
- void set_speed(const Vector2 &p_speed);
- Vector2 get_speed() const;
+ void set_velocity(const Vector2 &p_velocity);
+ Vector2 get_velocity() const;
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
virtual String as_text() const override;
@@ -388,7 +388,7 @@ class InputEventScreenDrag : public InputEventFromWindow {
int index = 0;
Vector2 pos;
Vector2 relative;
- Vector2 speed;
+ Vector2 velocity;
protected:
static void _bind_methods();
@@ -403,8 +403,8 @@ public:
void set_relative(const Vector2 &p_relative);
Vector2 get_relative() const;
- void set_speed(const Vector2 &p_speed);
- Vector2 get_speed() const;
+ void set_velocity(const Vector2 &p_velocity);
+ Vector2 get_velocity() const;
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
virtual String as_text() const override;
diff --git a/core/io/image.h b/core/io/image.h
index dffc5a6a5f..29236a55e5 100644
--- a/core/io/image.h
+++ b/core/io/image.h
@@ -36,8 +36,6 @@
#include "core/math/rect2.h"
/**
- * @author Juan Linietsky <reduzio@gmail.com>
- *
* Image storage class. This is used to store an image in user memory, as well as
* providing some basic methods for image manipulation.
* Images can be loaded from a file, or registered into the Render object as textures.
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index ebe88fcf66..ce2435216b 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -699,8 +699,7 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
ERR_FAIL_COND_V_MSG(!to_exists, Vector<Vector2>(), vformat("Can't get point path. Point with id: %d doesn't exist.", p_to_id));
if (a == b) {
- Vector<Vector2> ret;
- ret.push_back(Vector2(a->pos.x, a->pos.y));
+ Vector<Vector2> ret = { Vector2(a->pos.x, a->pos.y) };
return ret;
}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 1839ec7e04..130c202a61 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -37,9 +37,7 @@
#include "core/templates/oa_hash_map.h"
/**
- A* pathfinding algorithm
-
- @author Juan Linietsky <reduzio@gmail.com>
+ A* pathfinding algorithm.
*/
class AStar : public RefCounted {
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
index d16c5d3d62..8657dc068e 100644
--- a/core/math/disjoint_set.h
+++ b/core/math/disjoint_set.h
@@ -34,10 +34,6 @@
#include "core/templates/map.h"
#include "core/templates/vector.h"
-/**
- @author Marios Staikopoulos <marios@staik.net>
-*/
-
/* This DisjointSet class uses Find with path compression and Union by rank */
template <typename T, class C = Comparator<T>, class AL = DefaultAllocator>
class DisjointSet {
diff --git a/core/math/geometry_3d.cpp b/core/math/geometry_3d.cpp
index e1bce81b6b..98a2c27d93 100644
--- a/core/math/geometry_3d.cpp
+++ b/core/math/geometry_3d.cpp
@@ -644,14 +644,15 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes
Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross(right).normalized();
- Vector<Vector3> vertices;
-
Vector3 center = p.center();
+
// make a quad clockwise
- vertices.push_back(center - up * subplane_size + right * subplane_size);
- vertices.push_back(center - up * subplane_size - right * subplane_size);
- vertices.push_back(center + up * subplane_size - right * subplane_size);
- vertices.push_back(center + up * subplane_size + right * subplane_size);
+ Vector<Vector3> vertices = {
+ center - up * subplane_size + right * subplane_size,
+ center - up * subplane_size - right * subplane_size,
+ center + up * subplane_size - right * subplane_size,
+ center + up * subplane_size + right * subplane_size
+ };
for (int j = 0; j < p_planes.size(); j++) {
if (j == i) {
@@ -762,14 +763,14 @@ Geometry3D::MeshData Geometry3D::build_convex_mesh(const Vector<Plane> &p_planes
}
Vector<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) {
- Vector<Plane> planes;
-
- planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x));
- planes.push_back(Plane(Vector3(-1, 0, 0), p_extents.x));
- planes.push_back(Plane(Vector3(0, 1, 0), p_extents.y));
- planes.push_back(Plane(Vector3(0, -1, 0), p_extents.y));
- planes.push_back(Plane(Vector3(0, 0, 1), p_extents.z));
- planes.push_back(Plane(Vector3(0, 0, -1), p_extents.z));
+ Vector<Plane> planes = {
+ Plane(Vector3(1, 0, 0), p_extents.x),
+ Plane(Vector3(-1, 0, 0), p_extents.x),
+ Plane(Vector3(0, 1, 0), p_extents.y),
+ Plane(Vector3(0, -1, 0), p_extents.y),
+ Plane(Vector3(0, 0, 1), p_extents.z),
+ Plane(Vector3(0, 0, -1), p_extents.z)
+ };
return planes;
}
diff --git a/core/object/object.h b/core/object/object.h
index 4fe2dff19b..602bd3cda1 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -52,10 +52,6 @@
#define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7]
#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7]
-/**
-@author Juan Linietsky <reduzio@gmail.com>
-*/
-
enum PropertyHint {
PROPERTY_HINT_NONE, ///< no hint provided.
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range.
diff --git a/core/os/pool_allocator.h b/core/os/pool_allocator.h
index 25b5061f62..11a252bc54 100644
--- a/core/os/pool_allocator.h
+++ b/core/os/pool_allocator.h
@@ -34,13 +34,12 @@
#include "core/typedefs.h"
/**
- @author Juan Linietsky <reduzio@gmail.com>
* Generic Pool Allocator.
* This is a generic memory pool allocator, with locking, compacting and alignment. (@TODO alignment)
* It used as a standard way to manage allocation in a specific region of memory, such as texture memory,
* audio sample memory, or just any kind of memory overall.
* (@TODO) abstraction should be greater, because in many platforms, you need to manage a nonreachable memory.
-*/
+ */
enum {
POOL_ALLOCATOR_INVALID_ID = -1 ///< default invalid value. use INVALID_ID( id ) to test
diff --git a/core/templates/hash_map.h b/core/templates/hash_map.h
index 82b3546f9d..fa5677cc70 100644
--- a/core/templates/hash_map.h
+++ b/core/templates/hash_map.h
@@ -40,7 +40,6 @@
/**
* @class HashMap
- * @author Juan Linietsky <reduzio@gmail.com>
*
* Implementation of a standard Hashing HashMap, for quick lookups of Data associated with a Key.
* The implementation provides hashers for the default types, if you need a special kind of hasher, provide
@@ -48,7 +47,8 @@
* @param TKey Key, search is based on it, needs to be hasheable. It is unique in this container.
* @param TData Data, data associated with the key
* @param Hasher Hasher object, needs to provide a valid static hash function for TKey
- * @param Comparator comparator object, needs to be able to safely compare two TKey values. It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check.
+ * @param Comparator comparator object, needs to be able to safely compare two TKey values.
+ * It needs to ensure that x == x for any items inserted in the map. Bear in mind that nan != nan when implementing an equality check.
* @param MIN_HASH_TABLE_POWER Miminum size of the hash table, as a power of two. You rarely need to change this parameter.
* @param RELATIONSHIP Relationship at which the hash table is resized. if amount of elements is RELATIONSHIP
* times bigger than the hash table, table is resized to solve this condition. if RELATIONSHIP is zero, table is always MIN_HASH_TABLE_POWER.
diff --git a/core/templates/set.h b/core/templates/set.h
index 9107459884..cdc6e8447d 100644
--- a/core/templates/set.h
+++ b/core/templates/set.h
@@ -582,6 +582,9 @@ public:
}
Element *lower_bound(const T &p_value) const {
+ if (!_data._root) {
+ return nullptr;
+ }
return _lower_bound(p_value);
}
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 4ada3b597a..e53c502f67 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -33,7 +33,6 @@
/**
* @class Vector
- * @author Juan Linietsky
* Vector container. Regular Vector Container. Use with care and for smaller arrays when possible. Use Vector for large arrays.
*/
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 20a371c3d0..be7ac1164e 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2134,8 +2134,11 @@
<constant name="JOY_BUTTON_SDL_MAX" value="21" enum="JoyButton">
The number of SDL game controller buttons.
</constant>
- <constant name="JOY_BUTTON_MAX" value="36" enum="JoyButton">
- The maximum number of game controller buttons: Android supports up to 36 buttons.
+ <constant name="JOY_BUTTON_MAX" value="128" enum="JoyButton">
+ The maximum number of game controller buttons supported by the engine. The actual limit may be lower on specific platforms:
+ - Android: Up to 36 buttons.
+ - Linux: Up to 80 buttons.
+ - Windows and macOS: Up to 128 buttons.
</constant>
<constant name="JOY_AXIS_INVALID" value="-1" enum="JoyAxis">
An invalid game controller axis.
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 7a2120379f..6f660c9a88 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -158,7 +158,7 @@
</member>
<member name="detail_normal" type="Texture2D" setter="set_texture" getter="get_texture">
Texture that specifies the per-pixel normal of the detail overlay.
- [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" enum="BaseMaterial3D.DetailUV" default="0">
Specifies whether to use [code]UV[/code] or [code]UV2[/code] for the detail layer. See [enum DetailUV] for options.
@@ -255,7 +255,7 @@
<member name="normal_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to specify the normal at a given pixel. The [code]normal_texture[/code] only uses the red and green channels; the blue and alpha channels are ignored. The normal read from [code]normal_texture[/code] is oriented around the surface normal provided by the [Mesh].
[b]Note:[/b] The mesh must have both normals and tangents defined in its vertex data. Otherwise, the normal map won't render correctly and will only appear to darken the whole surface. If creating geometry with [SurfaceTool], you can use [method SurfaceTool.generate_normals] and [method SurfaceTool.generate_tangents] to automatically generate normals and tangents respectively.
- [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="orm_texture" type="Texture2D" setter="set_texture" getter="get_texture">
</member>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index a7b2434def..44845947b1 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -115,7 +115,7 @@
<argument index="4" name="outline" type="float" default="0.0" />
<argument index="5" name="pixel_range" type="float" default="4.0" />
<description>
- Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [method FontData.set_multichannel_signed_distance_field] for more information and caveats about MSDF font rendering.
+ Draws a textured rectangle region of the multi-channel signed distance field texture at a given position, optionally modulated by a color. See [member FontData.multichannel_signed_distance_field] for more information and caveats about MSDF font rendering.
If [code]outline[/code] is positive, each alpha channel value of pixel in region is set to maximum value of true distance in the [code]outline[/code] radius.
Value of the [code]pixel_range[/code] should the same that was used during distance field texture generation.
</description>
diff --git a/doc/classes/CharacterBody2D.xml b/doc/classes/CharacterBody2D.xml
index 47ee5d5487..28a9107db6 100644
--- a/doc/classes/CharacterBody2D.xml
+++ b/doc/classes/CharacterBody2D.xml
@@ -95,37 +95,37 @@
<method name="is_on_ceiling" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "ceiling" or not.
</description>
</method>
<method name="is_on_ceiling_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "ceiling" or not.
</description>
</method>
<method name="is_on_floor" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "floor" or not.
</description>
</method>
<method name="is_on_floor_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "floor" or not.
</description>
</method>
<method name="is_on_wall" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "wall" or not.
</description>
</method>
<method name="is_on_wall_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "wall" or not.
</description>
</method>
<method name="move_and_slide">
diff --git a/doc/classes/CharacterBody3D.xml b/doc/classes/CharacterBody3D.xml
index e35471b4f6..819190fd69 100644
--- a/doc/classes/CharacterBody3D.xml
+++ b/doc/classes/CharacterBody3D.xml
@@ -81,37 +81,37 @@
<method name="is_on_ceiling" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "ceiling" or not.
</description>
</method>
<method name="is_on_ceiling_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with the ceiling on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "ceiling" or not.
</description>
</method>
<method name="is_on_floor" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "floor" or not.
</description>
</method>
<method name="is_on_floor_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with the floor on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "floor" or not.
</description>
</method>
<method name="is_on_wall" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "wall" or not.
</description>
</method>
<method name="is_on_wall_only" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the body collided only with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code].
+ Returns [code]true[/code] if the body collided only with a wall on the last call of [method move_and_slide]. Otherwise, returns [code]false[/code]. The [member up_direction] and [member floor_max_angle] are used to determine whether a surface is "wall" or not.
</description>
</method>
<method name="move_and_slide">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 3d8199831d..d5551e1e04 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -1113,6 +1113,12 @@
<description>
Emitted when the mouse leaves the control's [code]Rect[/code] area, provided its [member mouse_filter] lets the event reach it.
[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a child [Control] node, even if the mouse cursor is still inside the parent's [code]Rect[/code] area.
+ If you want to check whether the mouse truly left the area, ignoring any top nodes, you can use code like this:
+ [codeblock]
+ func _on_mouse_exited():
+ if not Rect2(Vector2(), rect_size).has_point(get_local_mouse_position()):
+ # Not hovering over area.
+ [/codeblock]
</description>
</signal>
<signal name="resized">
diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml
index 60c329935a..6473108866 100644
--- a/doc/classes/EditorNode3DGizmo.xml
+++ b/doc/classes/EditorNode3DGizmo.xml
@@ -12,11 +12,13 @@
<method name="_commit_handle" qualifiers="virtual">
<return type="void" />
<argument index="0" name="id" type="int" />
- <argument index="1" name="restore" type="Variant" />
- <argument index="2" name="cancel" type="bool" />
+ <argument index="1" name="secondary" type="bool" />
+ <argument index="2" name="restore" type="Variant" />
+ <argument index="3" name="cancel" type="bool" />
<description>
Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
+ The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method add_handles] for more information).
</description>
</method>
<method name="_commit_subgizmos" qualifiers="virtual">
@@ -32,16 +34,19 @@
<method name="_get_handle_name" qualifiers="virtual const">
<return type="String" />
<argument index="0" name="id" type="int" />
+ <argument index="1" name="secondary" type="bool" />
<description>
- Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]).
- Handles can be named for reference to the user when editing.
+ Override this method to return the name of an edited handle (handles must have been previously added by [method add_handles]). Handles can be named for reference to the user when editing.
+ The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
</description>
</method>
<method name="_get_handle_value" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="id" type="int" />
+ <argument index="1" name="secondary" type="bool" />
<description>
Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
+ The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
</description>
</method>
<method name="_get_subgizmo_transform" qualifiers="virtual const">
@@ -54,8 +59,10 @@
<method name="_is_handle_highlighted" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="id" type="int" />
+ <argument index="1" name="secondary" type="bool" />
<description>
Override this method to return [code]true[/code] whenever the given handle should be highlighted in the editor.
+ The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method add_handles] for more information).
</description>
</method>
<method name="_redraw" qualifiers="virtual">
@@ -67,10 +74,12 @@
<method name="_set_handle" qualifiers="virtual">
<return type="void" />
<argument index="0" name="id" type="int" />
- <argument index="1" name="camera" type="Camera3D" />
- <argument index="2" name="point" type="Vector2" />
+ <argument index="1" name="secondary" type="bool" />
+ <argument index="2" name="camera" type="Camera3D" />
+ <argument index="3" name="point" type="Vector2" />
<description>
Override this method to update the node properties when the user drags a gizmo handle (previously added with [method add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts.
+ The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method add_handles] for more information).
</description>
</method>
<method name="_set_subgizmo_transform" qualifiers="virtual">
@@ -120,6 +129,7 @@
<argument index="4" name="secondary" type="bool" default="false" />
<description>
Adds a list of handles (points) which can be used to edit the properties of the gizmo's Node3D. The [code]ids[/code] argument can be used to specify a custom identifier for each handle, if an empty [code]Array[/code] is passed, the ids will be assigned automatically from the [code]handles[/code] argument order.
+ The [code]secondary[/code] argument marks the added handles as secondary, meaning they will normally have less selection priority than regular handles. When the user is holding the shift key secondary handles will switch to have higher priority than regular handles. This change in priority can be used to place multiple handles at the same point while still giving the user control on their selection.
There are virtual methods which will be called upon editing of these handles. Call this method during [method _redraw].
</description>
</method>
diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml
index 3bcd9e7764..aa8237d69f 100644
--- a/doc/classes/EditorNode3DGizmoPlugin.xml
+++ b/doc/classes/EditorNode3DGizmoPlugin.xml
@@ -21,11 +21,14 @@
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="handle_id" type="int" />
- <argument index="2" name="restore" type="Variant" />
- <argument index="3" name="cancel" type="bool" />
+ <argument index="2" name="secondary" type="bool" />
+ <argument index="3" name="restore" type="Variant" />
+ <argument index="4" name="cancel" type="bool" />
<description>
Override this method to commit a handle being edited (handles must have been previously added by [method EditorNode3DGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
- If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos.
+ If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
+ The [code]secondary[/code] argument is [code]true[/code] when the committed handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information).
+ Called for this plugin's active gizmos.
</description>
</method>
<method name="_commit_subgizmos" qualifiers="virtual">
@@ -56,16 +59,20 @@
<return type="String" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="handle_id" type="int" />
+ <argument index="2" name="secondary" type="bool" />
<description>
- Override this method to provide gizmo's handle names. Called for this plugin's active gizmos.
+ Override this method to provide gizmo's handle names. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). Called for this plugin's active gizmos.
</description>
</method>
<method name="_get_handle_value" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="handle_id" type="int" />
+ <argument index="2" name="secondary" type="bool" />
<description>
- Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. Called for this plugin's active gizmos.
+ Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
+ The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information).
+ Called for this plugin's active gizmos.
</description>
</method>
<method name="_get_priority" qualifiers="virtual const">
@@ -94,8 +101,9 @@
<return type="bool" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="handle_id" type="int" />
+ <argument index="2" name="secondary" type="bool" />
<description>
- Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. Called for this plugin's active gizmos.
+ Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. The [code]secondary[/code] argument is [code]true[/code] when the requested handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information). Called for this plugin's active gizmos.
</description>
</method>
<method name="_is_selectable_when_hidden" qualifiers="virtual const">
@@ -115,10 +123,13 @@
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="handle_id" type="int" />
- <argument index="2" name="camera" type="Camera3D" />
- <argument index="3" name="screen_pos" type="Vector2" />
+ <argument index="2" name="secondary" type="bool" />
+ <argument index="3" name="camera" type="Camera3D" />
+ <argument index="4" name="screen_pos" type="Vector2" />
<description>
- Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. Called for this plugin's active gizmos.
+ Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts.
+ The [code]secondary[/code] argument is [code]true[/code] when the edited handle is secondary (see [method EditorNode3DGizmo.add_handles] for more information).
+ Called for this plugin's active gizmos.
</description>
</method>
<method name="_set_subgizmo_transform" qualifiers="virtual">
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index 2b0594902f..396592719d 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -70,7 +70,7 @@
The dialog's open or save mode, which affects the selection behavior. See [enum FileMode].
</member>
<member name="filters" type="PackedStringArray" setter="set_filters" getter="get_filters" default="PackedStringArray()">
- The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code].
+ The available file type filters. For example, this shows only [code].png[/code] and [code].gd[/code] files: [code]set_filters(PackedStringArray(["*.png ; PNG Images","*.gd ; GDScript Files"]))[/code]. Multiple file types can also be specified in a single filter. [code]"*.png, *.jpg, *.jpeg ; Supported Images"[/code] will show both PNG and JPEG files when selected.
</member>
<member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title" default="true">
If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [constant FILE_MODE_OPEN_FILE] will change the window title to "Open a File").
diff --git a/doc/classes/FontData.xml b/doc/classes/FontData.xml
index 0c8386784e..36976f7083 100644
--- a/doc/classes/FontData.xml
+++ b/doc/classes/FontData.xml
@@ -79,12 +79,6 @@
Returns text server font cache entry resource id.
</description>
</method>
- <method name="get_data" qualifiers="const">
- <return type="PackedByteArray" />
- <description>
- Returns contents of the dynamic font source file.
- </description>
- </method>
<method name="get_descent" qualifiers="const">
<return type="float" />
<argument index="0" name="cache_index" type="int" />
@@ -93,30 +87,6 @@
Returns font descent (number of pixels below the baseline).
</description>
</method>
- <method name="get_fixed_size" qualifiers="const">
- <return type="int" />
- <description>
- Returns font fixed size.
- </description>
- </method>
- <method name="get_font_name" qualifiers="const">
- <return type="String" />
- <description>
- Returns font family name.
- </description>
- </method>
- <method name="get_font_style" qualifiers="const">
- <return type="int" />
- <description>
- Returns font style flags, see [enum TextServer.FontStyle].
- </description>
- </method>
- <method name="get_font_style_name" qualifiers="const">
- <return type="String" />
- <description>
- Returns font style name.
- </description>
- </method>
<method name="get_glyph_advance" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="cache_index" type="int" />
@@ -180,12 +150,6 @@
Returns rectangle in the cache texture containing the glyph.
</description>
</method>
- <method name="get_hinting" qualifiers="const">
- <return type="int" enum="TextServer.Hinting" />
- <description>
- Returns the font hinting mode. Used by dynamic fonts only.
- </description>
- </method>
<method name="get_kerning" qualifiers="const">
<return type="Vector2" />
<argument index="0" name="cache_index" type="int" />
@@ -216,24 +180,6 @@
Returns list of language support overrides.
</description>
</method>
- <method name="get_msdf_pixel_range" qualifiers="const">
- <return type="int" />
- <description>
- Returns the width of the range around the shape between the minimum and maximum representable signed distance.
- </description>
- </method>
- <method name="get_msdf_size" qualifiers="const">
- <return type="int" />
- <description>
- Returns source font size used to generate MSDF textures.
- </description>
- </method>
- <method name="get_oversampling" qualifiers="const">
- <return type="float" />
- <description>
- Returns font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only.
- </description>
- </method>
<method name="get_scale" qualifiers="const">
<return type="float" />
<argument index="0" name="cache_index" type="int" />
@@ -346,18 +292,6 @@
Returns [code]true[/code] if a Unicode [code]char[/code] is available in the font.
</description>
</method>
- <method name="is_antialiased" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if font 8-bit anitialiased glyph rendering is supported and enabled.
- </description>
- </method>
- <method name="is_force_autohinter" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if auto-hinting is supported and preferred over font built-in hinting. Used by dynamic fonts only.
- </description>
- </method>
<method name="is_language_supported" qualifiers="const">
<return type="bool" />
<argument index="0" name="language" type="String" />
@@ -365,12 +299,6 @@
Returns [code]true[/code], if font supports given language ([url=https://en.wikipedia.org/wiki/ISO_639-1]ISO 639[/url] code).
</description>
</method>
- <method name="is_multichannel_signed_distance_field" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if glyphs of all sizes are rendered using single multichannel signed distance field generated from the dynamic font vector data.
- </description>
- </method>
<method name="is_script_supported" qualifiers="const">
<return type="bool" />
<argument index="0" name="script" type="String" />
@@ -455,13 +383,6 @@
Renders the range of characters to the font cache texture.
</description>
</method>
- <method name="set_antialiased">
- <return type="void" />
- <argument index="0" name="antialiased" type="bool" />
- <description>
- If set to [code]true[/code], 8-bit antialiased glyph rendering is used, otherwise 1-bit rendering is used. Used by dynamic fonts only.
- </description>
- </method>
<method name="set_ascent">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
@@ -471,13 +392,6 @@
Sets the font ascent (number of pixels above the baseline).
</description>
</method>
- <method name="set_data">
- <return type="void" />
- <argument index="0" name="data" type="PackedByteArray" />
- <description>
- Sets font source data, e.g contents of the dynamic font source file.
- </description>
- </method>
<method name="set_descent">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
@@ -487,41 +401,6 @@
Sets the font descent (number of pixels below the baseline).
</description>
</method>
- <method name="set_fixed_size">
- <return type="void" />
- <argument index="0" name="fixed_size" type="int" />
- <description>
- Sets the fixed size for the font.
- </description>
- </method>
- <method name="set_font_name">
- <return type="void" />
- <argument index="0" name="name" type="String" />
- <description>
- Sets the font family name.
- </description>
- </method>
- <method name="set_font_style">
- <return type="void" />
- <argument index="0" name="style" type="int" />
- <description>
- Sets the font style flags, see [enum TextServer.FontStyle].
- </description>
- </method>
- <method name="set_font_style_name">
- <return type="void" />
- <argument index="0" name="name" type="String" />
- <description>
- Sets the font style name.
- </description>
- </method>
- <method name="set_force_autohinter">
- <return type="void" />
- <argument index="0" name="force_autohinter" type="bool" />
- <description>
- If set to [code]true[/code] auto-hinting is preferred over font built-in hinting.
- </description>
- </method>
<method name="set_glyph_advance">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
@@ -573,13 +452,6 @@
Sets rectangle in the cache texture containing the glyph.
</description>
</method>
- <method name="set_hinting">
- <return type="void" />
- <argument index="0" name="hinting" type="int" enum="TextServer.Hinting" />
- <description>
- Sets font hinting mode. Used by dynamic fonts only.
- </description>
- </method>
<method name="set_kerning">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
@@ -598,35 +470,6 @@
Adds override for [method is_language_supported].
</description>
</method>
- <method name="set_msdf_pixel_range">
- <return type="void" />
- <argument index="0" name="msdf_pixel_range" type="int" />
- <description>
- Sets the width of the range around the shape between the minimum and maximum representable signed distance.
- </description>
- </method>
- <method name="set_msdf_size">
- <return type="void" />
- <argument index="0" name="msdf_size" type="int" />
- <description>
- Sets source font size used to generate MSDF textures.
- </description>
- </method>
- <method name="set_multichannel_signed_distance_field">
- <return type="void" />
- <argument index="0" name="msdf" type="bool" />
- <description>
- If set to [code]true[/code], glyphs of all sizes are rendered using single multichannel signed distance field (MSDF) generated from the dynamic font vector data. MSDF rendering allows displaying the font at any scaling factor without blurriness, and without incurring a CPU cost when the font size changes (since the font no longer needs to be rasterized on the CPU). As a downside, font hinting is not available with MSDF. The lack of font hinting may result in less crisp and less readable fonts at small sizes.
- [b]Note:[/b] MSDF font rendering does not render glyphs with overlapping shapes correctly. Overlapping shapes are not valid per the OpenType standard, but are still commonly found in many font files, especially those converted by Google Fonts. To avoid issues with overlapping glyphs, consider downloading the font file directly from the type foundry instead of relying on Google Fonts.
- </description>
- </method>
- <method name="set_oversampling">
- <return type="void" />
- <argument index="0" name="oversampling" type="float" />
- <description>
- Sets font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only.
- </description>
- </method>
<method name="set_scale">
<return type="void" />
<argument index="0" name="cache_index" type="int" />
@@ -701,4 +544,45 @@
</description>
</method>
</methods>
+ <members>
+ <member name="antialiased" type="bool" setter="set_antialiased" getter="is_antialiased" default="true">
+ If set to [code]true[/code], font 8-bit anitialiased glyph rendering is supported and enabled.
+ </member>
+ <member name="data" type="PackedByteArray" setter="set_data" getter="get_data" default="PackedByteArray()">
+ Contents of the dynamic font source file.
+ </member>
+ <member name="fixed_size" type="int" setter="set_fixed_size" getter="get_fixed_size" default="0">
+ Font size, used only for the bitmap fonts.
+ </member>
+ <member name="font_name" type="String" setter="set_font_name" getter="get_font_name" default="&quot;&quot;">
+ Font family name.
+ </member>
+ <member name="font_style" type="int" setter="set_font_style" getter="get_font_style" default="0">
+ Font style flags, see [enum TextServer.FontStyle].
+ </member>
+ <member name="force_autohinter" type="bool" setter="set_force_autohinter" getter="is_force_autohinter" default="false">
+ If set to [code]true[/code], auto-hinting is supported and preffered over font built-in hinting. Used by dynamic fonts only.
+ </member>
+ <member name="hinting" type="int" setter="set_hinting" getter="get_hinting" enum="TextServer.Hinting" default="1">
+ Font hinting mode. Used by dynamic fonts only.
+ </member>
+ <member name="msdf_pixel_range" type="int" setter="set_msdf_pixel_range" getter="get_msdf_pixel_range" default="16">
+ The width of the range around the shape between the minimum and maximum representable signed distance.
+ </member>
+ <member name="msdf_size" type="int" setter="set_msdf_size" getter="get_msdf_size" default="48">
+ Source font size used to generate MSDF textures.
+ </member>
+ <member name="multichannel_signed_distance_field" type="bool" setter="set_multichannel_signed_distance_field" getter="is_multichannel_signed_distance_field" default="false">
+ If set to [code]true[/code], glyphs of all sizes are rendered using single multichannel signed distance field generated from the dynamic font vector data.
+ </member>
+ <member name="opentype_feature_overrides" type="Dictionary" setter="set_opentype_feature_overrides" getter="get_opentype_feature_overrides" default="{}">
+ Font OpenType feature set override.
+ </member>
+ <member name="oversampling" type="float" setter="set_oversampling" getter="get_oversampling" default="0.0">
+ Font oversampling factor, if set to [code]0.0[/code] global oversampling factor is used instead. Used by dynamic fonts only.
+ </member>
+ <member name="style_name" type="String" setter="set_font_style_name" getter="get_font_style_name" default="&quot;&quot;">
+ Font style name.
+ </member>
+ </members>
</class>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 46960d7cc4..575697f20d 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -214,6 +214,9 @@
<member name="minimap_size" type="Vector2" setter="set_minimap_size" getter="get_minimap_size" default="Vector2(240, 160)">
The size of the minimap rectangle. The map itself is based on the size of the grid area and is scaled to fit this rectangle.
</member>
+ <member name="panning_scheme" type="int" setter="set_panning_scheme" getter="get_panning_scheme" enum="GraphEdit.PanningScheme" default="0">
+ Defines the control scheme for panning with mouse wheel.
+ </member>
<member name="rect_clip_content" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
<member name="right_disconnects" type="bool" setter="set_right_disconnects" getter="is_right_disconnects_enabled" default="false">
If [code]true[/code], enables disconnection of existing connections in the GraphEdit by dragging the right end.
@@ -345,6 +348,14 @@
</description>
</signal>
</signals>
+ <constants>
+ <constant name="SCROLL_ZOOMS" value="0" enum="PanningScheme">
+ [kbd]Mouse Wheel[/kbd] will zoom, [kbd]Ctrl + Mouse Wheel[/kbd] will move the view.
+ </constant>
+ <constant name="SCROLL_PANS" value="1" enum="PanningScheme">
+ [kbd]Mouse Wheel[/kbd] will move the view, [kbd]Ctrl + Mouse Wheel[/kbd] will zoom.
+ </constant>
+ </constants>
<theme_items>
<theme_item name="activity" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
</theme_item>
@@ -367,7 +378,7 @@
<theme_item name="port_grab_distance_horizontal" data_type="constant" type="int" default="24">
The horizontal range within which a port can be grabbed (on both sides).
</theme_item>
- <theme_item name="port_grab_distance_vertical" data_type="constant" type="int" default="6">
+ <theme_item name="port_grab_distance_vertical" data_type="constant" type="int" default="26">
The vertical range within which a port can be grabbed (on both sides).
</theme_item>
<theme_item name="layout" data_type="icon" type="Texture2D">
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 4939e48e97..45b15331d2 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -141,10 +141,10 @@
Returns the strength of the joypad vibration: x is the strength of the weak motor, and y is the strength of the strong motor.
</description>
</method>
- <method name="get_last_mouse_speed" qualifiers="const">
+ <method name="get_last_mouse_velocity" qualifiers="const">
<return type="Vector2" />
<description>
- Returns the mouse speed for the last time the cursor was moved, and this until the next frame where the mouse moves. This means that even if the mouse is not moving, this function will still return the value of the last motion.
+ Returns the mouse velocity for the last time the cursor was moved, and this until the next frame where the mouse moves. This means that even if the mouse is not moving, this function will still return the value of the last motion.
</description>
</method>
<method name="get_magnetometer" qualifiers="const">
diff --git a/doc/classes/InputEventMouseMotion.xml b/doc/classes/InputEventMouseMotion.xml
index bd1ae367c2..ae573f70f4 100644
--- a/doc/classes/InputEventMouseMotion.xml
+++ b/doc/classes/InputEventMouseMotion.xml
@@ -4,7 +4,7 @@
Input event type for mouse motion events.
</brief_description>
<description>
- Contains mouse and pen motion information. Supports relative, absolute positions and speed. See [method Node._input].
+ Contains mouse and pen motion information. Supports relative, absolute positions and velocity. See [method Node._input].
[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>
@@ -19,11 +19,11 @@
The mouse position relative to the previous position (position at the last frame).
[b]Note:[/b] Since [InputEventMouseMotion] is only emitted when the mouse moves, the last event won't have a relative position of [code]Vector2(0, 0)[/code] when the user stops moving the mouse.
</member>
- <member name="speed" type="Vector2" setter="set_speed" getter="get_speed" default="Vector2(0, 0)">
- The mouse speed in pixels per second.
- </member>
<member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2(0, 0)">
Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
</member>
+ <member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
+ The mouse velocity in pixels per second.
+ </member>
</members>
</class>
diff --git a/doc/classes/InputEventScreenDrag.xml b/doc/classes/InputEventScreenDrag.xml
index 19c26e3a98..0b0550fbdd 100644
--- a/doc/classes/InputEventScreenDrag.xml
+++ b/doc/classes/InputEventScreenDrag.xml
@@ -19,8 +19,8 @@
<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2(0, 0)">
The drag position relative to the previous position (position at the last frame).
</member>
- <member name="speed" type="Vector2" setter="set_speed" getter="get_speed" default="Vector2(0, 0)">
- The drag speed.
+ <member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
+ The drag velocity.
</member>
</members>
</class>
diff --git a/doc/classes/InstancePlaceholder.xml b/doc/classes/InstancePlaceholder.xml
index e67232ebac..92dd9bc726 100644
--- a/doc/classes/InstancePlaceholder.xml
+++ b/doc/classes/InstancePlaceholder.xml
@@ -4,7 +4,7 @@
Placeholder for the root [Node] of a [PackedScene].
</brief_description>
<description>
- Turning on the option [b]Load As Placeholder[/b] for an instantiated scene in the editor causes it to be replaced by an [InstancePlaceholder] when running the game. This makes it possible to delay actually loading the scene until calling [method create_instance]. This is useful to avoid loading large scenes all at once by loading parts of it selectively.
+ Turning on the option [b]Load As Placeholder[/b] for an instantiated scene in the editor causes it to be replaced by an [InstancePlaceholder] when running the game, this will not replace the node in the editor. This makes it possible to delay actually loading the scene until calling [method create_instance]. This is useful to avoid loading large scenes all at once by loading parts of it selectively.
The [InstancePlaceholder] does not have a transform. This causes any child nodes to be positioned relatively to the [Viewport] from point (0,0), rather than their parent as displayed in the editor. Replacing the placeholder with a scene with a transform will transform children relatively to their parent again.
</description>
<tutorials>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index c3e3088d69..b376ab5cb0 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -174,7 +174,7 @@
<member name="caret_force_displayed" type="bool" setter="set_caret_force_displayed" getter="is_caret_force_displayed" default="false">
If [code]true[/code], the [LineEdit] will always show the caret, even if focus is lost.
</member>
- <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="false">
+ <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="true">
Allow moving caret, selecting and removing the individual composite character components.
[b]Note:[/b] [kbd]Backspace[/kbd] is always removing individual composite character components.
</member>
diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml
index 35e4451918..60137ab006 100644
--- a/doc/classes/MeshDataTool.xml
+++ b/doc/classes/MeshDataTool.xml
@@ -114,7 +114,7 @@
<argument index="1" name="edge" type="int" />
<description>
Returns specified edge associated with given face.
- Edge argument must 2 or less because a face only has three edges.
+ Edge argument must be either 0, 1, or 2 because a face only has three edges.
</description>
</method>
<method name="get_face_meta" qualifiers="const">
@@ -137,7 +137,7 @@
<argument index="1" name="vertex" type="int" />
<description>
Returns the specified vertex of the given face.
- Vertex argument must be 2 or less because faces contain three vertices.
+ Vertex argument must be either 0, 1, or 2 because faces contain three vertices.
</description>
</method>
<method name="get_format" qualifiers="const">
diff --git a/doc/classes/MeshInstance2D.xml b/doc/classes/MeshInstance2D.xml
index 6873edb3ae..5d5471c570 100644
--- a/doc/classes/MeshInstance2D.xml
+++ b/doc/classes/MeshInstance2D.xml
@@ -15,7 +15,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map that will be used if using the default [CanvasItemMaterial].
- [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The [Texture2D] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader.
diff --git a/doc/classes/MultiMeshInstance2D.xml b/doc/classes/MultiMeshInstance2D.xml
index 328ddff0eb..be01d96b5d 100644
--- a/doc/classes/MultiMeshInstance2D.xml
+++ b/doc/classes/MultiMeshInstance2D.xml
@@ -15,7 +15,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map that will be used if using the default [CanvasItemMaterial].
- [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The [Texture2D] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 753492ad34..d714fbc0d5 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -15,6 +15,7 @@
Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
[b]Groups:[/b] Nodes can be added to as many groups as you want to be easy to manage, you could create groups like "enemies" or "collectables" for example, depending on your game. See [method add_to_group], [method is_in_group] and [method remove_from_group]. You can then retrieve all nodes in these groups, iterate them and even call methods on groups via the methods on [SceneTree].
[b]Networking with nodes:[/b] After connecting to a server (or making one, see [ENetMultiplayerPeer]), 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.
+ [b]Note:[/b] The [code]script[/code] property is part of the [Object] class, not [Node]. It isn't exposed like most properties but does have a setter and getter ([code]set_script()[/code] and [code]get_script()[/code]).
</description>
<tutorials>
<link title="Nodes and scenes">$DOCS_URL/getting_started/step_by_step/nodes_and_scenes.html</link>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index e796cb2298..f5f6ba8b6d 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -27,6 +27,7 @@
The [code]in[/code] operator will evaluate to [code]true[/code] as long as the key exists, even if the value is [code]null[/code].
Objects also receive notifications. Notifications are a simple way to notify the object about different events, so they can all be handled together. See [method _notification].
[b]Note:[/b] Unlike references to a [RefCounted], references to an Object stored in a variable can become invalid without warning. Therefore, it's recommended to use [RefCounted] for data classes instead of [Object].
+ [b]Note:[/b] The [code]script[/code] property is not exposed like most properties, but it does have a setter and getter ([code]set_script()[/code] and [code]get_script()[/code]).
</description>
<tutorials>
<link title="When and how to avoid using nodes for everything">$DOCS_URL/tutorials/best_practices/node_alternatives.html</link>
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index 8a8d6e73f0..8973857ace 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -117,7 +117,7 @@
The custom color to use to draw the shape in the editor and at run-time if [b]Visible Collision Shapes[/b] is enabled in the [b]Debug[/b] menu. This color will be highlighted at run-time if the [RayCast3D] is colliding with something.
If set to [code]Color(0.0, 0.0, 0.0)[/code] (by default), the color set in [member ProjectSettings.debug/shapes/collision/shape_color] is used.
</member>
- <member name="debug_shape_thickness" type="float" setter="set_debug_shape_thickness" getter="get_debug_shape_thickness" default="2.0">
+ <member name="debug_shape_thickness" type="int" setter="set_debug_shape_thickness" getter="get_debug_shape_thickness" default="2">
If set to [code]1[/code], a line is used as the debug shape. Otherwise, a truncated pyramid is drawn to represent the [RayCast3D]. Requires [b]Visible Collision Shapes[/b] to be enabled in the [b]Debug[/b] menu for the debug shape to be visible at run-time.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true">
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index 32abd1caea..48d27ee0c0 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -66,9 +66,6 @@
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2(0, 0)">
The texture's drawing offset.
</member>
- <member name="opacity" type="float" setter="set_opacity" getter="get_opacity" default="1.0">
- The objects' visibility on a scale from [code]0[/code] fully invisible to [code]1[/code] fully visible.
- </member>
<member name="pixel_size" type="float" setter="set_pixel_size" getter="get_pixel_size" default="0.01">
The size of one pixel's width on the sprite to scale it in 3D.
</member>
diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml
index 660afb5a89..2d40167d4e 100644
--- a/doc/classes/SpriteFrames.xml
+++ b/doc/classes/SpriteFrames.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SpriteFrames" inherits="Resource" version="4.0">
<brief_description>
- Sprite frame library for AnimatedSprite2D.
+ Sprite frame library for AnimatedSprite2D and AnimatedSprite3D.
</brief_description>
<description>
- Sprite frame library for [AnimatedSprite2D]. Contains frames and animation data for playback.
+ Sprite frame library for an [AnimatedSprite2D] or [AnimatedSprite3D] node. 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>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 26ad20e85b..e120f79236 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -942,7 +942,7 @@
<member name="caret_blink_speed" type="float" setter="set_caret_blink_speed" getter="get_caret_blink_speed" default="0.65">
Duration (in seconds) of a caret's blinking cycle.
</member>
- <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="false">
+ <member name="caret_mid_grapheme" type="bool" setter="set_caret_mid_grapheme_enabled" getter="is_caret_mid_grapheme_enabled" default="true">
Allow moving caret, selecting and removing the individual composite character components.
[b]Note:[/b] [kbd]Backspace[/kbd] is always removing individual composite character components.
</member>
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 443716435a..64989eb98b 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -261,6 +261,13 @@
Returns font family name.
</description>
</method>
+ <method name="font_get_opentype_feature_overrides" qualifiers="const">
+ <return type="Dictionary" />
+ <argument index="0" name="font_rid" type="RID" />
+ <description>
+ Returns font OpenType feature set override.
+ </description>
+ </method>
<method name="font_get_oversampling" qualifiers="const">
<return type="float" />
<argument index="0" name="font_rid" type="RID" />
@@ -663,6 +670,14 @@
Sets the font family name.
</description>
</method>
+ <method name="font_set_opentype_feature_overrides">
+ <return type="void" />
+ <argument index="0" name="font_rid" type="RID" />
+ <argument index="1" name="overrides" type="Dictionary" />
+ <description>
+ Sets font OpenType feature set override.
+ </description>
+ </method>
<method name="font_set_oversampling">
<return type="void" />
<argument index="0" name="font_rid" type="RID" />
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index fb4ac630ba..aa6c93456b 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -261,6 +261,13 @@
Returns font family name.
</description>
</method>
+ <method name="_font_get_opentype_feature_overrides" qualifiers="virtual const">
+ <return type="Dictionary" />
+ <argument index="0" name="font_rid" type="RID" />
+ <description>
+ Returns font OpenType feature set override.
+ </description>
+ </method>
<method name="_font_get_oversampling" qualifiers="virtual const">
<return type="float" />
<argument index="0" name="font_rid" type="RID" />
@@ -550,6 +557,7 @@
<argument index="0" name="font_rid" type="RID" />
<argument index="1" name="force_autohinter" type="bool" />
<description>
+ If set to [code]true[/code] auto-hinting is preffered over font built-in hinting.
</description>
</method>
<method name="_font_set_global_oversampling" qualifiers="virtual">
@@ -670,6 +678,14 @@
Sets the font family name.
</description>
</method>
+ <method name="_font_set_opentype_feature_overrides" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="font_rid" type="RID" />
+ <argument index="1" name="overrides" type="Dictionary" />
+ <description>
+ Sets font OpenType feature set override.
+ </description>
+ </method>
<method name="_font_set_oversampling" qualifiers="virtual">
<return type="void" />
<argument index="0" name="font_rid" type="RID" />
diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml
index a160eceb35..f0cbe09fb9 100644
--- a/doc/classes/TextureRect.xml
+++ b/doc/classes/TextureRect.xml
@@ -10,15 +10,15 @@
<link title="3D Voxel Demo">https://godotengine.org/asset-library/asset/676</link>
</tutorials>
<members>
- <member name="expand" type="bool" setter="set_expand" getter="has_expand" default="false">
- If [code]true[/code], the texture scales to fit its bounding rectangle.
- </member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" default="false">
If [code]true[/code], texture is flipped horizontally.
</member>
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v" default="false">
If [code]true[/code], texture is flipped vertically.
</member>
+ <member name="ignore_texture_size" type="bool" setter="set_ignore_texture_size" getter="get_ignore_texture_size" default="false">
+ If [code]true[/code], the size of the texture won't be considered for minimum size calculation, so the [TextureRect] can be shrunk down past the texture size. Useful for preventing [TextureRect]s from breaking GUI layout regardless of their texture size.
+ </member>
<member name="mouse_filter" type="int" setter="set_mouse_filter" getter="get_mouse_filter" overrides="Control" enum="Control.MouseFilter" default="1" />
<member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureRect.StretchMode" default="0">
Controls the texture's behavior when resizing the node's bounding rectangle. See [enum StretchMode].
@@ -28,28 +28,25 @@
</member>
</members>
<constants>
- <constant name="STRETCH_SCALE_ON_EXPAND" value="0" enum="StretchMode">
- Scale to fit the node's bounding rectangle, only if [code]expand[/code] is [code]true[/code]. Default [code]stretch_mode[/code], for backwards compatibility. Until you set [code]expand[/code] to [code]true[/code], the texture will behave like [constant STRETCH_KEEP].
- </constant>
- <constant name="STRETCH_SCALE" value="1" enum="StretchMode">
+ <constant name="STRETCH_SCALE" value="0" enum="StretchMode">
Scale to fit the node's bounding rectangle.
</constant>
- <constant name="STRETCH_TILE" value="2" enum="StretchMode">
+ <constant name="STRETCH_TILE" value="1" enum="StretchMode">
Tile inside the node's bounding rectangle.
</constant>
- <constant name="STRETCH_KEEP" value="3" enum="StretchMode">
+ <constant name="STRETCH_KEEP" value="2" enum="StretchMode">
The texture keeps its original size and stays in the bounding rectangle's top-left corner.
</constant>
- <constant name="STRETCH_KEEP_CENTERED" value="4" enum="StretchMode">
+ <constant name="STRETCH_KEEP_CENTERED" value="3" enum="StretchMode">
The texture keeps its original size and stays centered in the node's bounding rectangle.
</constant>
- <constant name="STRETCH_KEEP_ASPECT" value="5" enum="StretchMode">
+ <constant name="STRETCH_KEEP_ASPECT" value="4" enum="StretchMode">
Scale the texture to fit the node's bounding rectangle, but maintain the texture's aspect ratio.
</constant>
- <constant name="STRETCH_KEEP_ASPECT_CENTERED" value="6" enum="StretchMode">
+ <constant name="STRETCH_KEEP_ASPECT_CENTERED" value="5" enum="StretchMode">
Scale the texture to fit the node's bounding rectangle, center it and maintain its aspect ratio.
</constant>
- <constant name="STRETCH_KEEP_ASPECT_COVERED" value="7" enum="StretchMode">
+ <constant name="STRETCH_KEEP_ASPECT_COVERED" value="6" enum="StretchMode">
Scale the texture so that the shorter side fits the bounding rectangle. The other side clips to the node's limits.
</constant>
</constants>
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 361b698fa2..1cba995366 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -303,16 +303,19 @@
</signals>
<constants>
<constant name="TWEEN_PROCESS_PHYSICS" value="0" enum="TweenProcessMode">
- The [Tween] updates during physics frame.
+ The [Tween] updates during the physics frame.
</constant>
<constant name="TWEEN_PROCESS_IDLE" value="1" enum="TweenProcessMode">
- The [Tween] updates during idle
+ The [Tween] updates during the idle frame.
</constant>
<constant name="TWEEN_PAUSE_BOUND" value="0" enum="TweenPauseMode">
+ If the [Tween] has a bound node, it will process when that node can process (see [member Node.process_mode]). Otherwise it's the same as [constant TWEEN_PAUSE_STOP].
</constant>
<constant name="TWEEN_PAUSE_STOP" value="1" enum="TweenPauseMode">
+ If [SceneTree] is paused, the [Tween] will also pause.
</constant>
<constant name="TWEEN_PAUSE_PROCESS" value="2" enum="TweenPauseMode">
+ The [Tween] will process regardless of whether [SceneTree] is paused.
</constant>
<constant name="TRANS_LINEAR" value="0" enum="TransitionType">
The animation is interpolated linearly.
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 6c39efd2f9..f593134557 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -110,7 +110,9 @@
<return type="float" />
<argument index="0" name="with" type="Vector2" />
<description>
- Returns the cross product of this vector and [code]with[/code].
+ Returns the 2D analog of the cross product for this vector and [code]with[/code].
+ This is the signed area of the parallelogram formed by the two vectors. If the second vector is clockwise from the first vector, then the cross product is the positive area. If counter-clockwise, the cross product is the negative area.
+ [b]Note:[/b] Cross product is not defined in 2D mathematically. This method embeds the 2D vectors in the XY plane of 3D space and uses their cross product's Z component as the analog.
</description>
</method>
<method name="cubic_interpolate" qualifiers="const">
diff --git a/doc/translations/ar.po b/doc/translations/ar.po
index 4ed6776561..caaf1ad7f1 100644
--- a/doc/translations/ar.po
+++ b/doc/translations/ar.po
@@ -14,12 +14,13 @@
# Alaa alden Aldroubi <alaa.aldroubi@gmail.com>, 2021.
# يزن حمزه <yznhamzeh@gmail.com>, 2021.
# HASSAN GAMER - حسن جيمر <gamerhassan55@gmail.com>, 2022.
+# Spirit <i8bou3@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-01-03 03:53+0000\n"
-"Last-Translator: HASSAN GAMER - حسن جيمر <gamerhassan55@gmail.com>\n"
+"PO-Revision-Date: 2022-01-10 13:18+0000\n"
+"Last-Translator: Spirit <i8bou3@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/ar/>\n"
"Language: ar\n"
@@ -71,9 +72,8 @@ msgid "Method Descriptions"
msgstr "أوصا٠الدوال"
#: doc/tools/make_rst.py
-#, fuzzy
msgid "Theme Property Descriptions"
-msgstr "أوصا٠المÙلكية"
+msgstr "أوصا٠خاصية الثمات"
#: doc/tools/make_rst.py
msgid "Inherits:"
@@ -89,15 +89,15 @@ msgstr ""
#: doc/tools/make_rst.py
msgid "Default"
-msgstr ""
+msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ"
#: doc/tools/make_rst.py
msgid "Setter"
-msgstr ""
+msgstr "واضع"
#: doc/tools/make_rst.py
msgid "value"
-msgstr ""
+msgstr "قيمة"
#: doc/tools/make_rst.py
msgid "Getter"
@@ -2829,7 +2829,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3823,8 +3828,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9425,15 +9428,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15546,9 +15551,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15564,17 +15568,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15582,8 +15587,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15591,16 +15598,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15959,6 +15970,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16445,7 +16489,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22233,111 +22285,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23784,9 +23972,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23843,7 +24036,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25572,6 +25767,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب المَعلم."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29583,7 +29867,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33479,7 +33763,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33493,7 +33777,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33717,7 +34002,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34706,7 +34991,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34775,9 +35060,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34868,12 +35153,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -34899,13 +35178,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35255,7 +35527,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38408,6 +38680,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40157,6 +40432,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40277,6 +40556,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44744,7 +45027,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45507,6 +45792,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48105,9 +48402,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51453,6 +51748,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52219,6 +52520,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52925,7 +53236,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53123,7 +53434,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54257,13 +54568,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60726,7 +61037,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61831,7 +62144,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/ca.po b/doc/translations/ca.po
index 96ab70929c..3ff232366a 100644
--- a/doc/translations/ca.po
+++ b/doc/translations/ca.po
@@ -2857,7 +2857,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3851,8 +3856,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9445,15 +9448,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15540,9 +15545,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15558,17 +15562,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15576,8 +15581,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15585,16 +15592,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15954,6 +15965,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16439,7 +16477,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22223,111 +22269,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23772,9 +23953,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23831,7 +24017,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25560,6 +25748,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29565,7 +29841,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33456,7 +33732,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33470,7 +33746,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33694,7 +33971,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34663,7 +34940,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34731,9 +35008,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34825,12 +35102,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34854,13 +35125,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35208,7 +35472,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38352,6 +38616,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40082,6 +40349,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40202,6 +40473,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44660,7 +44935,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45423,6 +45700,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48022,9 +48311,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51367,6 +51654,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52133,6 +52426,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52834,7 +53137,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53032,7 +53335,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54166,13 +54469,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60624,7 +60927,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61728,7 +62033,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index 0df1f347d0..a802e3a7ac 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -2737,7 +2737,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3731,8 +3736,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9312,15 +9315,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15387,9 +15392,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15405,17 +15409,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15423,8 +15428,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15432,16 +15439,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15801,6 +15812,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16286,7 +16324,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22044,111 +22090,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23588,9 +23769,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23647,7 +23833,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25367,6 +25555,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29356,7 +29632,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33228,7 +33504,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33242,7 +33518,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33466,7 +33743,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34423,7 +34700,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34491,9 +34768,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34585,12 +34862,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34614,13 +34885,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34968,7 +35232,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38100,6 +38364,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39830,6 +40097,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39947,6 +40218,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44404,7 +44679,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45167,6 +45444,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47760,9 +48049,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51095,6 +51382,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51857,6 +52150,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52554,7 +52857,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52752,7 +53055,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53886,13 +54189,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60335,7 +60638,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61438,7 +61743,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/cs.po b/doc/translations/cs.po
index ac77c85061..9179bf7651 100644
--- a/doc/translations/cs.po
+++ b/doc/translations/cs.po
@@ -3238,7 +3238,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4232,8 +4237,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9833,15 +9836,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15943,9 +15948,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15958,20 +15962,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Vrací [code]true[/code] pokud si jsou [code]a[/code] a [code]b[/code] "
+"přiblížně rovny."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15979,8 +15987,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15988,16 +15998,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16380,6 +16394,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Vrací [code]true[/code] pokud [code]s[/code] je nula nebo téměř nula."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16866,7 +16913,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22661,111 +22716,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Vrátí sinus parametru."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24211,9 +24402,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24270,7 +24466,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25999,6 +26197,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Vrátí sinus parametru."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30015,7 +30302,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33912,7 +34199,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33926,7 +34213,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34150,7 +34438,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35139,7 +35427,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35210,9 +35498,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35303,12 +35591,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35334,13 +35616,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35690,7 +35965,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38845,6 +39120,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40600,6 +40878,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40720,6 +41002,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45188,7 +45474,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45951,6 +46239,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48551,9 +48851,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51899,6 +52197,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52664,6 +52968,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53371,7 +53685,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53569,7 +53883,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54704,13 +55018,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61206,7 +61520,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62310,7 +62626,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/de.po b/doc/translations/de.po
index 8b52b03270..6c8d12e11f 100644
--- a/doc/translations/de.po
+++ b/doc/translations/de.po
@@ -3619,8 +3619,13 @@ msgid "Gamepad button 22."
msgstr "Gamepad-Taste 22."
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Die maximale Anzahl der Tasten des Game-Controllers."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4732,8 +4737,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -11291,15 +11294,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -17565,9 +17570,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -17580,20 +17584,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Gibt [code]true[/code] zurück wenn Einstellung welche durch [code]name[/"
+"code]angegeben ist, existiert, ansonsten [code]false[/code]."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -17601,8 +17609,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -17610,16 +17620,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -18006,6 +18020,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Entfernt die Animation mit dem key [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Entfernt die Animation mit dem key [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Entfernt die Animation mit dem key [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Entfernt die Animation mit dem key [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Liefert die Position des Punktes bei Index [code]Punkt[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Entfernt die Animation mit dem key [code]name[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -18495,7 +18542,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -24307,111 +24362,252 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "Legt den aktuell sichtbaren Rahmen der Textur fest."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Gibt den Sinus des Parameters zurück."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "Entfernt das Element der Arrays dessen Position übergeben wurde."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+"Entfernt den Punkt bei Index [code]Punkt[/code] aus dem Überblendungsbereich."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "Wird verwendet, um Eigenschaften im Editor zu gruppieren."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -25868,9 +26064,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25927,7 +26128,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -27669,6 +27872,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Der Name des Audiobusses des Bereichs."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -31716,7 +32008,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -35625,7 +35917,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -35639,7 +35931,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -35863,7 +36156,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -36865,7 +37158,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -36940,9 +37233,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -37035,12 +37328,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -37067,13 +37354,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37432,7 +37712,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -40594,6 +40874,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -42373,6 +42656,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -42494,6 +42781,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -47052,7 +47343,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -47821,6 +48114,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -50452,9 +50757,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"AABB besteht aus einer Position, einer Größe und mehreren Hilfsfunktionen. "
"Es wird typischerweise für schnelle Überlappungstests verwendet."
@@ -53820,6 +54123,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -54589,6 +54898,17 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "Wird ausgegeben, wenn eine Vorlage hinzugefügt wird."
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -55305,7 +55625,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -55510,7 +55830,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -56659,13 +56979,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -63240,7 +63560,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
"Tweens sind nützlich für Animationen, bei denen eine numerische Eigenschaft "
"über einen Bereich von Werten interpoliert werden muss. Der Name [i]tween[/"
@@ -64398,8 +64720,17 @@ msgstr ""
"[code]length[/code] begrenzt wird."
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Gibt das Kreuzprodukt aus diesem Vektor und [code]mit[/code] zurück."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
#, fuzzy
diff --git a/doc/translations/el.po b/doc/translations/el.po
index f983a43b79..91be47cf2d 100644
--- a/doc/translations/el.po
+++ b/doc/translations/el.po
@@ -2750,7 +2750,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3744,8 +3749,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9346,15 +9349,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15467,9 +15472,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15485,17 +15489,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15503,8 +15508,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15512,16 +15519,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15880,6 +15891,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16366,7 +16410,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22154,111 +22206,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23705,9 +23893,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23764,7 +23957,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25493,6 +25688,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "ΕπιστÏέφει το ημίτονο της παÏαμέτÏου."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29504,7 +29788,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33400,7 +33684,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33414,7 +33698,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33638,7 +33923,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34621,7 +34906,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34690,9 +34975,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34783,12 +35068,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -34814,13 +35093,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35170,7 +35442,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38323,6 +38595,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40060,6 +40335,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40180,6 +40459,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44647,7 +44930,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45410,6 +45695,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48008,9 +48305,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51356,6 +51651,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52122,6 +52423,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52828,7 +53139,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53026,7 +53337,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54160,13 +54471,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60629,7 +60940,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61734,7 +62047,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/es.po b/doc/translations/es.po
index 59ace9c817..bec08603ba 100644
--- a/doc/translations/es.po
+++ b/doc/translations/es.po
@@ -28,12 +28,13 @@
# Manuel Cantón Guillén <manuelcanton8@gmail.com>, 2021.
# Rémi Verschelde <akien@godotengine.org>, 2021.
# Rémi Verschelde <remi@godotengine.org>, 2021.
+# Alfonso V <alfonsov96@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2021-12-16 20:56+0000\n"
-"Last-Translator: Rémi Verschelde <remi@godotengine.org>\n"
+"PO-Revision-Date: 2022-01-09 14:56+0000\n"
+"Last-Translator: Alfonso V <alfonsov96@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/es/>\n"
"Language: es\n"
@@ -41,7 +42,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.10\n"
+"X-Generator: Weblate 4.10.1\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -90,77 +91,95 @@ msgstr "Descripciones de Propiedades"
#: doc/tools/make_rst.py
msgid "Inherits:"
-msgstr ""
+msgstr "Hereda de:"
#: doc/tools/make_rst.py
msgid "Inherited By:"
-msgstr ""
+msgstr "Heredado por:"
#: doc/tools/make_rst.py
msgid "(overrides %s)"
-msgstr ""
+msgstr "(sobreescribe %s)"
#: doc/tools/make_rst.py
+#, fuzzy
msgid "Default"
-msgstr ""
+msgstr "Por defecto"
#: doc/tools/make_rst.py
+#, fuzzy
msgid "Setter"
-msgstr ""
+msgstr "Método Configurador o Setter"
#: doc/tools/make_rst.py
msgid "value"
-msgstr ""
+msgstr "valor"
#: doc/tools/make_rst.py
+#, fuzzy
msgid "Getter"
-msgstr ""
+msgstr "Método de Acceso al Valor o Getter"
#: doc/tools/make_rst.py
msgid ""
"This method should typically be overridden by the user to have any effect."
msgstr ""
+"Típicamente, este método debería ser sobreescrito por el usuario para que "
+"tenga algún efecto."
#: doc/tools/make_rst.py
+#, fuzzy
msgid ""
"This method has no side effects. It doesn't modify any of the instance's "
"member variables."
msgstr ""
+"Este método no tiene efectos secundarios. No modifica ninguna de las "
+"variables miembras de la instancia."
#: doc/tools/make_rst.py
msgid ""
"This method accepts any number of arguments after the ones described here."
msgstr ""
+"Este método permite agregar cualquier número de argumentos después de los "
+"descritos aquí."
#: doc/tools/make_rst.py
+#, fuzzy
msgid "This method is used to construct a type."
-msgstr ""
+msgstr "Este método se utiliza para construir un tipo."
#: doc/tools/make_rst.py
msgid ""
"This method doesn't need an instance to be called, so it can be called "
"directly using the class name."
msgstr ""
+"Este método no necesita una instancia para ser llamado, por lo que puede "
+"llamarse directamente utilizando el nombre de la clase."
#: doc/tools/make_rst.py
+#, fuzzy
msgid ""
"This method describes a valid operator to use with this type as left-hand "
"operand."
msgstr ""
+"Este método describe un operador tal que el tipo de la instancia que lo "
+"llama es considerado como operando izquierdo."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid "Built-in GDScript functions."
-msgstr "Funciones GDScript Incorporadas."
+msgstr "Funciones GDScript predefinidas."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"List of core built-in GDScript functions. Math functions and other "
"utilities. Everything else is provided by objects. (Keywords: builtin, built "
"in, global functions.)"
msgstr ""
-"Lista de funciones primordiales e incorporadas de GDScript. Funciones "
-"matemáticas y otras utilidades. Todo lo demás está proporcionado por "
-"objetos. (Palabras clave: incorporado, includido, funciones globales.)"
+"Lista de funciones primitivas de GDScript. Funciones matemáticas y otras "
+"utilidades. Todo lo demás está proporcionado por objetos. (Palabras clave: "
+"incorporado, includido, tipo primitivo, funciones globales.)"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -187,6 +206,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns a color according to the standardized [code]name[/code] with "
"[code]alpha[/code] ranging from 0 to 1.\n"
@@ -230,7 +250,7 @@ msgid ""
msgstr ""
"Devuelve el arco coseno de [code]s[/code] en radianes. Se usa para obtener "
"el ángulo del coseno de [code]s[/code]. [code]s[/code] debe estar entre "
-"[code]-1.0[/code] y [code]1.0[/code] (inclusive), en otro caso, [method "
+"[code]-1.0[/code] y [code]1.0[/code] (incluyéndolos); en otro caso, [method "
"acos] devolverá [constant NAN].\n"
"[codeblock]\n"
"# c es 0.523599 o 30 grados si se convierte con rad2deg(s)\n"
@@ -250,14 +270,15 @@ msgid ""
msgstr ""
"Devuelve el arcoseno de [code]s[/code] en radianes. Se usa para obtener el "
"ángulo del seno de [code]s[/code]. [code]s[/code] debe estar entre "
-"[code]-1.0[/code] y [code]1.0[/code] (inclusive), en otro caso, [method "
+"[code]-1.0[/code] y [code]1.0[/code] (incluyéndolos); en otro caso, [method "
"asin] devolverá [constant NAN].\n"
"[codeblock]\n"
-"# s es 0.523599 o 30 grados si se convierte conrad2deg(s)\n"
+"# s es 0.523599 o 30 grados si se convierte con rad2deg(s)\n"
"s = asin(0.5)\n"
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Asserts that the [code]condition[/code] is [code]true[/code]. If the "
"[code]condition[/code] is [code]false[/code], an error is generated. When "
@@ -286,8 +307,8 @@ msgstr ""
"Afirma que la condición [code]condition[/code] es [code]true[/code]. Si la "
"condición [code]condition[/code] es [code]false[/code], se genera un error. "
"Cuando se ejecuta desde el editor, el proyecto en ejecución también se "
-"pausará hasta que lo reanude. Esto se puede utilizar como una forma más "
-"restrictiva de [method push_error] para informar errores a los "
+"pausará hasta que el usuario lo reanude. Esto se puede utilizar como una "
+"forma más restrictiva de [method push_error] para informar errores a los "
"desarrolladores de proyectos o usuarios de complementos.\n"
"[b]Nota:[/b] Por razones de rendimiento, el código dentro de [method assert] "
"solo se ejecuta en compilaciones de depuración o cuando se ejecuta el "
@@ -310,6 +331,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns the arc tangent of [code]s[/code] in radians. Use it to get the "
"angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == "
@@ -321,7 +343,7 @@ msgid ""
"[/codeblock]"
msgstr ""
"Devuelve el arco tangente de [code]s[/code] en radianes. Úsalo para obtener "
-"el ángulo de la tangente de un ángulo en trigonometría: "
+"el ángulo a partir de la tangente de un ángulo en trigonometría: "
"[code]atan(tan(angle)) == angle[/code].\n"
"El método no puede saber en qué cuadrante el ángulo se encuentra. Vea "
"[method atan2] si tienes tanto [code]y[/code] como [code]x[/code]\n"
@@ -330,6 +352,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns the arc tangent of [code]y/x[/code] in radians. Use to get the angle "
"of tangent [code]y/x[/code]. To compute the value, the method takes into "
@@ -339,8 +362,8 @@ msgid ""
"a = atan2(0, -1) # a is 3.141593\n"
"[/codeblock]"
msgstr ""
-"Devuelve la arcotangente de [code]y/x[/code] en radianes. Usalo para obtener "
-"el angulo de la tangente [code]y/x[/code]. Para obtener el valor, el metodo "
+"Devuelve la arcotangente de [code]y/x[/code] en radianes. Úsalo para obtener "
+"el ángulo de la tangente [code]y/x[/code]. Para obtener el valor, el método "
"tiene en cuenta el signo de ambos argumentos para determinar el cuadrante.\n"
"Nota importante: La coordenada Y es la primera, por convención.\n"
"[codeblock]\n"
@@ -364,14 +387,15 @@ msgstr ""
#: modules/gdscript/doc_classes/@GDScript.xml
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+#, fuzzy
msgid ""
"Converts a 2D point expressed in the cartesian coordinate system (X and Y "
"axis) to the polar coordinate system (a distance from the origin and an "
"angle)."
msgstr ""
"Convierte un punto 2D expresado en el sistema de coordenadas cartesianas "
-"(ejes X e Y) en el sistema de coordenadas polares (una distancia del origen "
-"y un ángulo)."
+"(ejes X e Y) al sistema de coordenadas polares (una distancia desde el "
+"origen y un ángulo)."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -485,7 +509,7 @@ msgstr "Convierte de decibeles a energía lineal (audio)."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid "Deprecated alias for [method step_decimals]."
-msgstr "Alias obsoleto del [method step_decimals]."
+msgstr "Alias obsoleto para [method step_decimals]."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -506,6 +530,7 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Compares two values by checking their actual contents, recursing into any "
"`Array` or `Dictionary` up to its deepest level.\n"
@@ -525,6 +550,23 @@ msgid ""
"want a true content-aware comparison, you have to use [code]deep_equal[/"
"code]."
msgstr ""
+"Compara dos valores evaluando sus contenidos actuales, recorriendo de forma "
+"recursiva todo `Array` o `Dictionary` hasta su mayor profundidad.\n"
+"Es comparable con [code]==[/code] en varios aspectos:\n"
+"- Para [code]null[/code], [code]int[/code], [code]float[/code], "
+"[code]String[/code], [code]Object[/code] y [code]RID[/code], tanto "
+"[code]deep_equal[/code] como [code]==[/code] operan de la misma forma.\n"
+"- Para [code]Dictionary[/code], [code]==[/code] considera igualdad si, y "
+"solo si, ambas variables apuntan a exactamente el mismo [code]Dictionary[/"
+"code], sin recursión o verificación de su contenido.\n"
+"- Para [code]Array[/code], [code]==[/code] considera igualdad si, y solo si, "
+"cada ítem en el primer [code]Array[/code] es igual a su contraparte en el "
+"segundo [code]Array[/code], según el mismo [code]==[/code]. Esto implica que "
+"[code]==[/code] es recursivo para evaluar elementos de tipo [code]Array[/"
+"code], pero no para elementos de tipo [code]Dictionary[/code].\n"
+"En síntesis, siempre que un [code]Dictionary[/code] está potencialmente "
+"involucrado, si se quiere una comparación real de contenidos, se debe "
+"utilizar [code]deep_equal[/code]."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -540,12 +582,13 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Converts a dictionary (previously created with [method inst2dict]) back to "
"an instance. Useful for deserializing."
msgstr ""
"Convierte un diccionario (que fue creado previamente con [method inst2dict]) "
-"de nuevo a una instancia. Es útil para deserializar."
+"de nuevo en una instancia. Es útil para deserializar."
#: modules/gdscript/doc_classes/@GDScript.xml
#, fuzzy
@@ -588,6 +631,7 @@ msgstr ""
"avanzadas, utilice [Tween] o [AnimationPlayer]."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"The natural exponential function. It raises the mathematical constant [b]e[/"
"b] to the power of [code]s[/code] and returns it.\n"
@@ -602,7 +646,7 @@ msgstr ""
"potencia de [code]s[/code] y la devuelve.\n"
"[b]e[/b] tiene un valor aproximado de 2,71828, y puede obtenerse con "
"[code]exp(1)[/code].\n"
-"Para los exponentes a otras bases se utiliza el método [method pow].\n"
+"Para potencias con otras bases se utiliza el método [method pow].\n"
"[codeblock]\n"
"a = exp(2) # Aproximadamente 7.39\n"
"[/codeblock]"
@@ -641,12 +685,13 @@ msgid ""
"[/codeblock]\n"
"For the integer remainder operation, use the % operator."
msgstr ""
-"Devuelve el resto en punto flotante de [code]a/b[/code], manteniendo el "
-"signo de [code]a[/code].\n"
+"Devuelve el residuo real de [code]a/b[/code], manteniendo el signo de "
+"[code]a[/code].\n"
"[codeblock]\n"
-"r = fmod(7, 5.5) # r es 1.5\n"
+"# residuo es 1.5\n"
+"var residuo = fmod(7, 5.5)\n"
"[/codeblock]\n"
-"Para la operación módulo de números enteros, utilice el operador %."
+"Para la operación del resto de los números enteros, utilice el operador %."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -668,11 +713,11 @@ msgid ""
" 1.5 0.0 0.0\n"
"[/codeblock]"
msgstr ""
-"Devuelve el módulo en punto flotante de [code]a/b[/code] que envuelve por "
-"igual en positivo y en negativo.\n"
+"Devuelve el módulo real de [code]a/b[/code] que envuelve por igual en "
+"positivo y en negativo.\n"
"[codeblock]\n"
"for i in 7:\n"
-"var x = 0.5 * i - 1.5\n"
+" var x = 0.5 * i - 1.5\n"
" print(\"%4.1f %4.1f %4.1f\" % [x, fmod(x, 1.5), fposmod(x, 1.5)])\n"
"[/codeblock]\n"
"Produce:\n"
@@ -812,10 +857,11 @@ msgstr ""
"func _ready():\n"
" var id = get_instance_id()\n"
" var inst = instance_from_id(id)\n"
-" print(inst.foo) # Prints bar\n"
+" print(inst.foo) # Imprime bar\n"
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Returns an interpolation or extrapolation factor considering the range "
"specified in [code]from[/code] and [code]to[/code], and the interpolated "
@@ -836,6 +882,23 @@ msgid ""
"[/codeblock]\n"
"See also [method lerp] which performs the reverse of this operation."
msgstr ""
+"Devuelve un factor de interpolación o extrapolación, considerando el rango "
+"especificado en [code]from[/code] y [code]to[/code], y el valor interpolado "
+"especificado en [code]weight[/code]. El valor devuelto estará entre "
+"[code]0.0[/code] y [code]1.0[/code] si [code]weight[/code] está entre "
+"[code]from[/code] y [code]to[/code] (incluyéndolos). Si [code]weight[/code] "
+"está ubicado fuera de este rango, se devolverá un factor de extrapolación "
+"(valor de retorno menor que [code]0.0[/code] o mayor que [code]1.0[/code]).\n"
+"[codeblock]\n"
+"# La razón de interpolación en la llamada a `lerp()` de más abajo es 0.75.\n"
+"var middle = lerp(20, 30, 0.75)\n"
+"# `middle` ahora es 27.5.\n"
+"# Ahora, suponemos haber olvidado la razón original y queremos obtererla de "
+"vuelta.\n"
+"var ratio = inverse_lerp(20, 30, 27.5)\n"
+"# `ratio` ahora es 0.75.\n"
+"[/codeblock]\n"
+"Ver también [method lerp], el cual ejecuta la operación inversa a esta."
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -2202,6 +2265,7 @@ msgstr ""
"La constante del círculo, la circunferencia de la unidad círculo en radianes."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"Positive floating-point infinity. This is the result of floating-point "
"division when the divisor is [code]0.0[/code]. For negative infinity, use "
@@ -2214,8 +2278,18 @@ msgid ""
"code] will not result in [constant INF] and will result in a run-time error "
"instead."
msgstr ""
+"Infinito como número de punto flotante. Este es el resultado de una división "
+"real cuando el divisor es [code]0.0[/code]. Para el infinito negativo, "
+"utilizar [code]-INF[/code]. Dividir por [code]-0.0[/code] otorgará como "
+"resultado el infinito negativo si el numerador es positivo, de manera que no "
+"es lo mismo que dividir por [code]0.0[/code] (a pesar de que [code]0.0 == "
+"-0.0[/code] devuelve [code]true[/code]). [b]Nota:[/b] El infinito numérico "
+"solo es un concepto para números de punto flotante y no tiene un equivalente "
+"para enteros. La división de un entero por [code]0[/code] no resultará en "
+"[constant INF] y en su lugar arrojará un error en tiempo de ejecución."
#: modules/gdscript/doc_classes/@GDScript.xml
+#, fuzzy
msgid ""
"\"Not a Number\", an invalid floating-point value. [constant NAN] has "
"special properties, including that it is not equal to itself ([code]NAN == "
@@ -2227,6 +2301,15 @@ msgid ""
"[code]0[/code] will not result in [constant NAN] and will result in a run-"
"time error instead."
msgstr ""
+"\"Not a Number\" (\"No es un Número\"), un decimal de valor inválido. "
+"[constant NAN] tiene propiedades especiales, incluyendo que no es igual a si "
+"mismo([code]NAN==NAN[/code] devuelve [code]false[/code]). Es una salida dada "
+"por algunas operaciones inválidas, como dividir un decimal [code]0.0[/code] "
+"por [code]0.0[/code].\n"
+"[b]Nota:[/b] \"Not a Number\" es solo un concepto con números decimales, y "
+"no tiene un equivalente para enteros. Dividiendo un entero por [code]0[/"
+"code] no resultará en [constante NAN] y en su lugar arrojará un error en "
+"tiempo de ejecución."
#: doc/classes/@GlobalScope.xml
msgid "Global scope constants and variables."
@@ -3641,8 +3724,13 @@ msgid "Gamepad button 22."
msgstr "Botón 2 del mando de videojuegos."
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Representa el máximo número de botones de joystick soportados."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -3901,16 +3989,22 @@ msgstr ""
"Touch y Windows MR)."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI note OFF message. See the documentation of [InputEventMIDI] for "
"information of how to use MIDI inputs."
msgstr ""
+"Mensaje de APAGADO en una nota MIDI. Ver la documentación de "
+"[InputEventMIDI] para información sobre cómo utilizar inputs MIDI."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI note ON message. See the documentation of [InputEventMIDI] for "
"information of how to use MIDI inputs."
msgstr ""
+"Mensaje de ENCENDIDO en una nota MIDI. Ver la documentación de "
+"[InputEventMIDI] para información sobre cómo utilizar inputs MIDI."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -3919,35 +4013,55 @@ msgid ""
msgstr ""
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI control change message. This message is sent when a controller value "
"changes. Controllers include devices such as pedals and levers."
msgstr ""
+"Mensaje de cambio de control MIDI. Este mensaje se envía cuando cambia un "
+"valor en el controlador. Los controladores son aparatos como pedales y "
+"palancas."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI program change message. This message sent when the program patch number "
"changes."
msgstr ""
+"Mensaje de cambio de programa MIDI. Este mensaje se envía cuando el número "
+"de versión del programa cambia."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI channel pressure message. This message is most often sent by pressing "
"down on the key after it \"bottoms out\". This message is different from "
"polyphonic after-touch as it indicates the highest pressure across all keys."
msgstr ""
+"Mensaje de presión en canal MIDI. Este mensaje suele enviarse al presionar "
+"una tecla después de que esta alcanza su punto mínimo. Este mensaje es "
+"diferente al de after-touch polifónico, ya que indica la presión más alta de "
+"entre todas las teclas."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI pitch bend message. This message is sent to indicate a change in the "
"pitch bender (wheel or lever, typically)."
msgstr ""
+"Mensaje de alteración de tono MIDI. Este mensaje se envía para indicar un "
+"cambio en la herramienta de alteración de tono del instrumento (normalmente "
+"una rueda o palanca)."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI system exclusive message. This has behavior exclusive to the device "
"you're receiving input from. Getting this data is not implemented in Godot."
msgstr ""
+"Mensaje exclusivo del sistema MIDI. Este tiene comportamiento exclusivo para "
+"el aparato desde el cual se está recibiendo input. La obtención de estos "
+"datos no está implementada en Godot."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -3956,16 +4070,23 @@ msgid ""
msgstr ""
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI song position pointer message. Gives the number of 16th notes since the "
"start of the song. Getting this data is not implemented in Godot."
msgstr ""
+"Mensaje de puntero a posición en canción MIDI. Otorga el número de "
+"semicorcheas (o decimosextas) desde el inicio de la canción. La obtención de "
+"estos datos no está implementada en Godot."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI song select message. Specifies which sequence or song is to be played. "
"Getting this data is not implemented in Godot."
msgstr ""
+"Mensaje de selección de canción MIDI. Especifica qué secuencia o canción se "
+"reproducirá. La obtención de estos datos no está implementada en Godot."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -3974,30 +4095,42 @@ msgid ""
msgstr ""
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI timing clock message. Sent 24 times per quarter note when "
"synchronization is required."
msgstr ""
+"Mensaje de reloj sincronizador MIDI. Se envía 24 veces por nota negra (o "
+"cuarta) cuando se requiere sincronización."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI start message. Start the current sequence playing. This message will be "
"followed with Timing Clocks."
msgstr ""
+"Mensaje de inicio MIDI. Inicia la secuencia actual. El envío de este mensaje "
+"es seguido de Timing Clocks."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid "MIDI continue message. Continue at the point the sequence was stopped."
msgstr ""
+"Mensaje de continuación MIDI. Continúa desde el punto en el cual la pista "
+"fue previamente detenida."
#: doc/classes/@GlobalScope.xml
msgid "MIDI stop message. Stop the current sequence."
-msgstr ""
+msgstr "Mensaje de detención MIDI. Detiene la secuencia actual."
#: doc/classes/@GlobalScope.xml
+#, fuzzy
msgid ""
"MIDI active sensing message. This message is intended to be sent repeatedly "
"to tell the receiver that a connection is alive."
msgstr ""
+"Mensaje de percepción activa MIDI. La intención de este mensaje es que se "
+"envíe repetidamente para informar al recibidor que la conexión sigue en pie."
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4757,8 +4890,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -4802,6 +4933,7 @@ msgstr ""
"Devuelve [code]true[/code] si este [AABB] contiene completamente a otro."
#: doc/classes/AABB.xml
+#, fuzzy
msgid ""
"Returns a copy of this [AABB] expanded to include a given point.\n"
"[b]Example:[/b]\n"
@@ -4813,16 +4945,28 @@ msgid ""
"var box2 = box.expand(Vector3(0, -1, 2))\n"
"[/codeblock]"
msgstr ""
+"Devuelve una copia de este [AABB] expandido para incluir un punto dado.\n"
+"[b]Ejemplo:[/b]\n"
+"[codeblock]\n"
+"# posición (-3, 2, 0), tamaño (1, 1, 1)\n"
+"var box = AABB(Vector3(-3, 2, 0), Vector3(1, 1, 1))\n"
+"# posición (-3, -1, 0), tamaño (3, 4, 2), de manera que ajustamos tanto el "
+"AABB original como el Vector3(0, -1, 2)\n"
+"var box2 = box.expand(Vector3(0, -1, 2))\n"
+"[/codeblock]"
#: doc/classes/AABB.xml
msgid "Returns the volume of the [AABB]."
msgstr "Devuelve el volumen del [AABB]."
#: doc/classes/AABB.xml
+#, fuzzy
msgid ""
"Returns the center of the [AABB], which is equal to [member position] + "
"([member size] / 2)."
msgstr ""
+"Devuelve el centro del [AABB], el cual es igual a [member position] + "
+"([member size] / 2)."
#: doc/classes/AABB.xml
msgid "Gets the position of the 8 endpoints of the [AABB] in space."
@@ -4995,12 +5139,17 @@ msgstr ""
"al diálogo y devuelve el botón creado."
#: doc/classes/AcceptDialog.xml
+#, fuzzy
msgid ""
"Returns the label used for built-in text.\n"
"[b]Warning:[/b] This is a required internal node, removing and freeing it "
"may cause a crash. If you wish to hide it or any of its children, use their "
"[member CanvasItem.visible] property."
msgstr ""
+"Devuelve la etiqueta utilizada por un texto integrado.\n"
+"[b]Aviso:[/b] Este es un Nodo Interno requerido, removerlo o liberarlo puede "
+"resultar en un colapso. Si deseas ocultarlo o cualquiera de sus Hijos, usa "
+"la propiedad [member CanvasItem.visible]."
#: doc/classes/AcceptDialog.xml
msgid ""
@@ -12286,15 +12435,19 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr "Representa el tamaño del enum [enum FFT_Size]."
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+#, fuzzy
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr "Efecto de audio usado para grabar el sonido de un micrófono."
#: doc/classes/AudioEffectRecord.xml
+#, fuzzy
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
"Permite al usuario grabar el sonido desde un micrófono. Establece y obtiene "
"el formato en el que se grabará el archivo de audio (8-bit, 16-bit o "
@@ -20140,9 +20293,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -20155,20 +20307,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Devuelve [code]true[/code] si existe el ajuste especificado por [code]name[/"
+"code], [code]false[/code] en caso contrario."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -20176,8 +20332,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -20185,16 +20343,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -20681,6 +20843,39 @@ msgstr ""
"Deje el enfoque. Ningún otro control podrá recibir la entrada del teclado."
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Elimina la animación con la clave [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Elimina la animación con la clave [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Elimina la animación con la clave [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Elimina la animación con la clave [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Devuelve el índice del artículo con el [code]id[/code] dado."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Devuelve el índice del artículo con el [code]id[/code] dado."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -21412,7 +21607,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -29288,22 +29491,25 @@ msgid ""
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
"Interfaz del Sistema de Control de Versiones (VCS) que lee y escribe en el "
"VCS local en uso."
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
msgstr ""
"Usado por el editor para mostrar la información extraída del VCS en el "
"editor. La implementación de esta API está incluida en los addons de VCS, "
@@ -29315,150 +29521,244 @@ msgstr ""
"proporcionar una experiencia de plug-n-play."
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr "Elimina un Autoload [code]name[/code] de la lista."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
msgstr ""
-"Crea un commit de versión si el addon se inicializa, si no, regresa sin "
-"hacer nada. Utiliza los archivos que han sido preparados previamente, con el "
-"mensaje de confirmación establecido en un valor como el proporcionado en el "
-"argumento."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
+msgstr "Crea una instancia de [code]class[/code]."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
-msgstr ""
-"Devuelve una [Array] de objetos del [Dictionary] que contiene la diferencia "
-"desdel el VCS en uso, si se inicializa un addon VCS, si no, devuelve un "
-"objeto [Array] vacio. El contenido de la diferencia también consiste en "
-"algunas líneas contextuales que proporcionan contexto al cambio de línea "
-"observado en el archivo.\n"
-"Cada objeto [Dictionary] tiene el contenido de la línea diferencia bajo las "
-"claves:\n"
-"- [code]\"content\"[/code] para almacenar una [String] que contiene el "
-"contenido de la línea\n"
-"- [code]\"status\"[/code] para almacenar una [String] que contiene [code]\"+"
-"\"[/code] en caso de que el contenido sea una adición de línea pero almacena "
-"un [code]\"-\"[/code] en caso de eliminación y una cadena vacía en caso de "
-"que el contenido de la línea no sea ni una adición ni una eliminación.\n"
-"- [code]\"new_line_number\"[/code] para almacenar un número entero que "
-"contenga el nuevo número de línea del contenido de la línea.\n"
-"- [code]\"line_count\"[/code] para almacenar un entero que contenga el "
-"número de líneas del contenido de la línea.\n"
-"- [code]\"old_line_number\"[/code] para almacenar un entero que contiene el "
-"número de línea antiguo del contenido de la línea.\n"
-"- [code]\"offset\"[/code] para almacenar el offset del cambio de línea desde "
-"el primer contenido de línea contextual."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
#, fuzzy
+msgid "Discards the changes made in file present at [code]file_path[/code]."
+msgstr "Guarda la escena como un archivo en [code]path[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
-msgstr ""
-"Devuelve un [Dictionary] que contiene la ruta del cambio de archivo "
-"detectado mapeado a un número entero, lo que significa qué tipo de cambio ha "
-"experimentado el archivo correspondiente.\n"
-"Los siguientes valores enteros se están utilizando para significar que el "
-"archivo detectado es:\n"
-"- [code]0[/code]: Nuevo en el directorio de trabajo del VCS\n"
-"- [code]1[/code]: Modificado\n"
-"- [code]2[/code]: Renombrado\n"
-"- [code]3[/code]: Borrado\n"
-"- [code]4[/code]: Cambiado de tipo"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
-msgstr "Devuelve el nombre del proyecto del directorio de trabajo del VCS."
+#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "Devuelve la ruta actual que se está viendo en el [FileSystemDock]."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
-"Devuelve el nombre del VCS si el VCS ha sido inicializado, si no, devuelve "
-"una cadena vacía."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
-"Inicializa el addon VCS si no lo ha hecho ya. Usa el valor del argumento "
-"como la ruta al directorio de trabajo del proyecto. Crea el commit inicial "
-"si es necesario. Devuelve [code]true[/code] si no se produce ningún fallo, "
-"si no, devuelve [code]false[/code]."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
-"Devuelve [code]true[/code] si el addon está listo para responder a las "
-"llamadas de la función, si no, devuelve [code]false[/code]."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+"Devuelve un [Array] que contiene los Ids de los dispositivos de todos los "
+"joypads conectados actualmente."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Devuelve el nombre del nodo en [code]idx[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a branch from the local VCS."
+msgstr "Elimina un nodo de la selección."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "Elimina un nodo de la selección."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
msgstr ""
-"Devuelve [code]true[/code] si el addon VCS ha sido inicializado, si no, "
-"devuelve [code]false[/code]."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
msgstr ""
-"Apaga el complemento del VCS para permitir que el código de limpieza se "
-"ejecute cuando sea necesario. Devuelve [code]true[/code] si no se produce "
-"ningún fallo, si no devuelve [code]false[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "Añade la cámara [code]feed[/code] al servidor de la cámara."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
msgstr ""
-"Establece el archivo que debe ser confirmado cuando se llama al [method "
-"EditorVCSInterface.commit]. El argumento debería contener la ruta absoluta."
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "Se utiliza para agrupar las propiedades en el editor."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A new file has been added."
+msgstr "Emitido cuando se ha añadido una nueva interfaz."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A file is encountered from the staged area."
+msgstr "Estado: Desconectado del servidor."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
-"Devuelve al estado sin añadir el archivo que se preparó previamente para ser "
-"confirmado, de modo que ya no se confirma cuando se llama al [method "
-"EditorVCSInterface.commit]. El argumento debe contener la ruta absoluta."
#: doc/classes/EncodedObjectAsID.xml
msgid "Holds a reference to an [Object]'s instance ID."
@@ -31401,13 +31701,15 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
-"Añade [code]filter[/code] como filtro personalizado; [code]filter[/code] "
-"debe tener la forma [code]\"filename.extension ; Description\"[/code]. Por "
-"ejemplo, [code]\"*.png ; Imágenes PNG\"[/code]."
#: doc/classes/FileDialog.xml
msgid "Clear all the added filters in the dialog."
@@ -31464,7 +31766,9 @@ msgstr "La ruta de archivo actualmente seleccionada del diálogo de archivo."
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
"Los filtros de tipo de archivo disponibles. Por ejemplo, esto muestra sólo "
"los archivos [code].png[/code] y [code].gd[/code]: "
@@ -33790,6 +34094,104 @@ msgstr "El [Gradient] que se usará para rellenar la textura."
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr "El número de muestras de color que se obtendrán del [Gradient]."
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "Gradient-filled 2D texture."
+msgstr "Textura llena de gradientes."
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+"GradientTexture utiliza un [Gradient] para rellenar los datos de la textura. "
+"El gradiente se rellenará de izquierda a derecha usando los colores "
+"obtenidos del gradiente. Esto significa que la textura no representa "
+"necesariamente una copia exacta del gradiente, sino una interpolación de "
+"muestras obtenidas del gradiente a pasos fijos (ver [member width])."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "El [Gradient] que se usará para rellenar la textura."
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr "El número de muestras de color que se obtendrán del [Gradient]."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr "El número de muestras de color que se obtendrán del [Gradient]."
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -39188,7 +39590,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -44326,9 +44728,10 @@ msgid "Returns the number of faces in this [Mesh]."
msgstr "Devuelve el número de caras en esta [Mesh]."
#: doc/classes/MeshDataTool.xml
+#, fuzzy
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
"Devuelve un borde específico asociado a una cara determinada.\n"
"El argumento de borde debe ser 2 o menos porque una cara sólo tiene tres "
@@ -44343,9 +44746,11 @@ msgid "Calculates and returns the face normal of the given face."
msgstr "Calcula y devuelve la cara normal de la cara dada."
#: doc/classes/MeshDataTool.xml
+#, fuzzy
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
"Devuelve el vértice especificado de la cara dada.\n"
"El argumento del vértice debe ser 2 o menos porque las caras contienen tres "
@@ -44615,9 +45020,10 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]."
msgstr "La [Mesh] que será dibujada por la [MeshInstance2D]."
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
+#, fuzzy
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -45892,7 +46298,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -45968,9 +46374,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -46067,12 +46473,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -46099,13 +46499,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -46492,7 +46885,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -50973,6 +51366,7 @@ msgstr ""
"usados."
#: doc/classes/OS.xml
+#, fuzzy
msgid ""
"Execute the file at the given path with the arguments passed as an array of "
"strings. Platform path resolution will take place. The resolved file must "
@@ -50991,6 +51385,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -53347,6 +53744,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -53482,6 +53883,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -59463,12 +59868,15 @@ msgstr ""
"el archivo de configuración)."
#: doc/classes/ProjectSettings.xml
+#, fuzzy
msgid ""
"Sets the value of a setting.\n"
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
"Establece el valor de un ajuste.\n"
"[b]Ejemplo:[/b]\n"
@@ -60493,6 +60901,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -63716,9 +64136,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"[Rect2] consta de una posición, un tamaño y varias funciones de utilidad. Se "
"utiliza típicamente para pruebas de superposición rápida.\n"
@@ -68144,6 +68562,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -69095,6 +69519,17 @@ msgstr ""
"Si [code]true[/code], el deslizador mostrará las marcas de los valores "
"mínimo y máximo."
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "Emitido cuando se inicia el scrolling."
+
#: doc/classes/SliderJoint.xml
#, fuzzy
msgid "Slider between two PhysicsBodies in 3D."
@@ -70023,9 +70458,10 @@ msgstr ""
"con las texturas de base."
#: doc/classes/SpatialMaterial.xml
+#, fuzzy
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -70290,7 +70726,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -71751,13 +72187,13 @@ msgstr "Representa el tamaño del enum [enum DrawFlags]."
#: doc/classes/SpriteFrames.xml
#, fuzzy
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr "Biblioteca de fotogramas de Sprite para AnimatedSprite2D."
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -80018,7 +80454,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
"Los Tweens son útiles para las animaciones que requieren que una propiedad "
"numérica sea interpolada en un rango de valores. El nombre [i]tween[/i] "
@@ -81602,8 +82040,17 @@ msgstr ""
"[code]length[/code]."
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Devuelve el producto cruzado de este vector y [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
#, fuzzy
diff --git a/doc/translations/fa.po b/doc/translations/fa.po
index 214910a78f..4e18b8c1e3 100644
--- a/doc/translations/fa.po
+++ b/doc/translations/fa.po
@@ -13,12 +13,13 @@
# MSKF <walkingdeadstudio@outlook.com>, 2020.
# ItzMiad44909858f5774b6d <maidggg@gmail.com>, 2020.
# ahmad maftoon <ahmadmaftoon.1387@gmail.com>, 2021.
+# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2021-05-14 20:34+0000\n"
-"Last-Translator: ahmad maftoon <ahmadmaftoon.1387@gmail.com>\n"
+"PO-Revision-Date: 2022-01-09 14:57+0000\n"
+"Last-Translator: Seyed Fazel Alavi <fazel8195@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot-class-reference/fa/>\n"
"Language: fa\n"
@@ -26,7 +27,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.7-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -34,7 +35,7 @@ msgstr "تعریÙ"
#: doc/tools/make_rst.py
msgid "Tutorials"
-msgstr "آموزش‌ها"
+msgstr "آموزش ها"
#: doc/tools/make_rst.py
msgid "Properties"
@@ -42,7 +43,7 @@ msgstr "خصوصیات"
#: doc/tools/make_rst.py
msgid "Methods"
-msgstr "توابع"
+msgstr "روش ها"
#: doc/tools/make_rst.py
msgid "Theme Properties"
@@ -50,7 +51,7 @@ msgstr "خصوصیات زمینه"
#: doc/tools/make_rst.py
msgid "Signals"
-msgstr "سیگنال‌ها"
+msgstr "سیگنال ها"
#: doc/tools/make_rst.py
msgid "Enumerations"
@@ -3175,7 +3176,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4169,8 +4175,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9769,15 +9773,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15884,9 +15890,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15902,17 +15907,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15920,8 +15926,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15929,16 +15937,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16298,6 +16310,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16783,7 +16822,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22567,111 +22614,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24117,9 +24299,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24176,7 +24363,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25905,6 +26094,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29913,7 +30190,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33807,7 +34084,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33821,7 +34098,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34045,7 +34323,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35022,7 +35300,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35090,9 +35368,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35184,12 +35462,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -35213,13 +35485,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35567,7 +35832,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38717,6 +38982,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40461,6 +40729,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40581,6 +40853,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45041,7 +45317,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45804,6 +46082,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48406,9 +48696,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51754,6 +52042,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52520,6 +52814,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53226,7 +53530,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53424,7 +53728,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54558,13 +54862,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61019,7 +61323,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62124,7 +62430,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/fi.po b/doc/translations/fi.po
index 3719071c3f..717b65f172 100644
--- a/doc/translations/fi.po
+++ b/doc/translations/fi.po
@@ -2763,7 +2763,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3757,8 +3762,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9358,15 +9361,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15466,9 +15471,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15484,17 +15488,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15502,8 +15507,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15511,16 +15518,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15879,6 +15890,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Laskee kahden vektorin ristitulon."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16365,7 +16409,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22153,111 +22205,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Palauttaa parametrin sinin."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23703,9 +23891,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23762,7 +23955,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25492,6 +25687,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Palauttaa parametrin sinin."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29508,7 +29792,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33404,7 +33688,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33418,7 +33702,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33642,7 +33927,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34624,7 +34909,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34693,9 +34978,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34786,12 +35071,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -34817,13 +35096,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35173,7 +35445,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38324,6 +38596,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40059,6 +40334,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40179,6 +40458,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44645,7 +44928,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45408,6 +45693,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48004,9 +48301,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51348,6 +51643,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52114,6 +52415,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52820,7 +53131,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53018,7 +53329,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54153,13 +54464,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60621,7 +60932,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61725,9 +62038,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-#, fuzzy
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Laskee kahden vektorin ristitulon."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/fil.po b/doc/translations/fil.po
index fbcff01819..71953d6a2e 100644
--- a/doc/translations/fil.po
+++ b/doc/translations/fil.po
@@ -2744,7 +2744,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3738,8 +3743,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9338,15 +9341,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15453,9 +15458,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15471,17 +15475,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15489,8 +15494,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15498,16 +15505,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15867,6 +15878,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16352,7 +16390,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22136,111 +22182,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23686,9 +23867,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23745,7 +23931,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25474,6 +25662,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29482,7 +29758,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33376,7 +33652,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33390,7 +33666,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33614,7 +33891,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34585,7 +34862,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34653,9 +34930,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34747,12 +35024,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34776,13 +35047,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35130,7 +35394,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38280,6 +38544,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40012,6 +40279,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40132,6 +40403,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44592,7 +44867,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45355,6 +45632,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47953,9 +48242,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51301,6 +51588,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52067,6 +52360,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52773,7 +53076,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52971,7 +53274,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54105,13 +54408,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60566,7 +60869,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61671,7 +61976,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/fr.po b/doc/translations/fr.po
index b2e5eda16a..c651d2489c 100644
--- a/doc/translations/fr.po
+++ b/doc/translations/fr.po
@@ -3654,8 +3654,13 @@ msgid "Gamepad button 22."
msgstr "Bouton 22 de la manette."
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Le nombre maximum de boutons supportés pour un contrôleur de jeu."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4767,8 +4772,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10983,15 +10986,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -17420,9 +17425,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -17435,20 +17439,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Retourne [code]true[/code] si le paramètre spécifié par [code]name[/code] "
+"existe, [code]false[/code] autrement."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -17456,8 +17464,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -17465,16 +17475,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -17868,6 +17882,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Supprime l’animation avec la touche [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Supprime l’animation avec la touche [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Supprime l’animation avec la touche [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Supprime l’animation avec la touche [code]name[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Retourne la position du point à l'index [code]point[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Supprime l’animation avec la touche [code]name[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -18356,7 +18403,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -24253,122 +24308,258 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+"Supprime un [code]name[/code] de chargement automatique à partir de la liste."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
+msgstr "Crée une instance de [code]class[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "Définit le trame présentement visible de l'animation."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
-msgstr ""
-"Retourne un [Dictionary] contenant le chemin d’accès de la modification de "
-"fichier détectée mappée à un entier signifiant quel type de modification le "
-"fichier correspondant a connu.\n"
-"Les valeurs d’entiers suivantes sont utilisées pour signifier que le fichier "
-"détecté est :\n"
-"- [code]0[/code] : Nouveau dans le répertoire de travail VCS\n"
-"- [code]1[/code] : Modifié\n"
-"- [code]2[/code] : Rebaptisé\n"
-"- [code]3[/code] : Supprimé\n"
-"- [code]4[/code] : Type changé"
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr "Retourne une représentation [String] de l'évènement."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Retourne le nom du nœud à [code]idx[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a branch from the local VCS."
+msgstr "Supprime un nœud de la sélection."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "Supprime un nœud de la sélection."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "Ajoute un [Shape2D] au propriétaire de la forme."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "Utilisé pour rassembler des propriétés ensemble dans l'éditeur."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A new file has been added."
+msgstr "Émis lorsqu'une nouvelle interface a été ajoutée."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A file is encountered from the staged area."
+msgstr "Statut : Déconnecté du serveur."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -25852,9 +26043,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25911,7 +26107,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -27687,6 +27885,96 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "Gradient-filled 2D texture."
+msgstr "Texture remplie de gradients."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Texture remplie de gradients."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -31774,7 +32062,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -35767,7 +36055,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -35781,7 +36069,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -36007,7 +36296,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -37014,7 +37303,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -37087,9 +37376,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -37185,12 +37474,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -37216,13 +37499,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37582,7 +37858,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -40785,6 +41061,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -42568,6 +42847,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -42690,6 +42973,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -47289,7 +47576,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -48055,6 +48344,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -50678,9 +50979,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"Une AABB est constituée en une position, une taille, et plusieurs fonctions "
"utilitaires. Principalement utilisée pour des tests de chevauchement rapides."
@@ -54060,6 +54359,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -54837,6 +55142,17 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "Émis lorsque le défilement est commencé."
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -55552,7 +55868,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -55751,7 +56067,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -56926,13 +57242,13 @@ msgstr ""
#: doc/classes/SpriteFrames.xml
#, fuzzy
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr "Bibliothèque de cadres Sprite pour AnimatedSprite2D."
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -63675,7 +63991,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -64793,8 +65111,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Calcule le produit vectoriel de deux vecteurs et [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/gl.po b/doc/translations/gl.po
index 438057cdb3..244164c299 100644
--- a/doc/translations/gl.po
+++ b/doc/translations/gl.po
@@ -2745,7 +2745,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3739,8 +3744,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9320,15 +9323,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15395,9 +15400,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15413,17 +15417,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15431,8 +15436,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15440,16 +15447,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15809,6 +15820,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16294,7 +16332,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22052,111 +22098,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23596,9 +23777,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23655,7 +23841,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25375,6 +25563,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29364,7 +29640,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33236,7 +33512,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33250,7 +33526,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33474,7 +33751,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34431,7 +34708,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34499,9 +34776,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34593,12 +34870,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34622,13 +34893,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34976,7 +35240,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38108,6 +38372,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39838,6 +40105,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39955,6 +40226,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44412,7 +44687,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45175,6 +45452,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47768,9 +48057,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51103,6 +51390,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51865,6 +52158,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52562,7 +52865,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52760,7 +53063,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53894,13 +54197,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60343,7 +60646,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61446,7 +61751,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/hi.po b/doc/translations/hi.po
index 0979c6c95d..9902e6e4d8 100644
--- a/doc/translations/hi.po
+++ b/doc/translations/hi.po
@@ -2743,7 +2743,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3737,8 +3742,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9318,15 +9321,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15393,9 +15398,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15411,17 +15415,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15429,8 +15434,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15438,16 +15445,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15807,6 +15818,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16292,7 +16330,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22050,111 +22096,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23594,9 +23775,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23653,7 +23839,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25373,6 +25561,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29362,7 +29638,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33234,7 +33510,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33248,7 +33524,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33472,7 +33749,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34429,7 +34706,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34497,9 +34774,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34591,12 +34868,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34620,13 +34891,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34974,7 +35238,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38106,6 +38370,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39836,6 +40103,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39953,6 +40224,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44410,7 +44685,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45173,6 +45450,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47766,9 +48055,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51101,6 +51388,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51863,6 +52156,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52560,7 +52863,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52758,7 +53061,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53892,13 +54195,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60341,7 +60644,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61444,7 +61749,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/hu.po b/doc/translations/hu.po
index 0a786cfcd4..c8ed5c9e02 100644
--- a/doc/translations/hu.po
+++ b/doc/translations/hu.po
@@ -2761,7 +2761,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3755,8 +3760,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9336,15 +9339,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15411,9 +15416,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15429,17 +15433,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15447,8 +15452,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15456,16 +15463,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15825,6 +15836,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16310,7 +16348,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22068,111 +22114,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23612,9 +23793,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23671,7 +23857,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25391,6 +25579,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29380,7 +29656,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33252,7 +33528,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33266,7 +33542,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33490,7 +33767,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34447,7 +34724,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34515,9 +34792,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34609,12 +34886,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34638,13 +34909,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34992,7 +35256,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38124,6 +38388,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39854,6 +40121,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39971,6 +40242,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44428,7 +44703,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45191,6 +45468,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47784,9 +48073,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51119,6 +51406,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51881,6 +52174,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52578,7 +52881,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52776,7 +53079,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53910,13 +54213,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60359,7 +60662,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61462,7 +61767,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/id.po b/doc/translations/id.po
index 4279718983..a65891f84e 100644
--- a/doc/translations/id.po
+++ b/doc/translations/id.po
@@ -2949,7 +2949,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3943,8 +3948,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9543,15 +9546,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15659,9 +15664,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15677,17 +15681,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15695,8 +15700,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15704,16 +15711,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16073,6 +16084,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16558,7 +16596,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22342,111 +22388,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Mengembalikan nilai sinus hiperbolik invers dari parameter."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23893,9 +24075,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23952,7 +24139,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25681,6 +25870,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29689,7 +29967,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33583,7 +33861,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33597,7 +33875,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33821,7 +34100,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34804,7 +35083,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34872,9 +35151,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34966,12 +35245,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34995,13 +35268,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35349,7 +35615,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38500,6 +38766,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40245,6 +40514,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40365,6 +40638,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44828,7 +45105,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45591,6 +45870,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48189,9 +48480,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51537,6 +51826,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52303,6 +52598,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53009,7 +53314,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53207,7 +53512,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54341,13 +54646,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60804,7 +61109,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61909,7 +62216,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/is.po b/doc/translations/is.po
index 871771e31d..1d1edf8a53 100644
--- a/doc/translations/is.po
+++ b/doc/translations/is.po
@@ -2744,7 +2744,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3738,8 +3743,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9319,15 +9322,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15394,9 +15399,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15412,17 +15416,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15430,8 +15435,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15439,16 +15446,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15808,6 +15819,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16293,7 +16331,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22051,111 +22097,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23595,9 +23776,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23654,7 +23840,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25374,6 +25562,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29363,7 +29639,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33235,7 +33511,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33249,7 +33525,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33473,7 +33750,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34430,7 +34707,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34498,9 +34775,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34592,12 +34869,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34621,13 +34892,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34975,7 +35239,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38107,6 +38371,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39837,6 +40104,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39954,6 +40225,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44411,7 +44686,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45174,6 +45451,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47767,9 +48056,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51102,6 +51389,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51864,6 +52157,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52561,7 +52864,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52759,7 +53062,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53893,13 +54196,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60342,7 +60645,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61445,7 +61750,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/it.po b/doc/translations/it.po
index e32a94b9cd..0ded58b016 100644
--- a/doc/translations/it.po
+++ b/doc/translations/it.po
@@ -3659,7 +3659,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4670,8 +4675,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10300,15 +10303,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -16492,9 +16497,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -16507,20 +16511,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Ritorna [code]true[/code] se l'impostazione specificata da [code]name[/code] "
+"esiste, [code]false[/code] altrimenti."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -16528,8 +16536,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -16537,16 +16547,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16929,6 +16943,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -17415,7 +17462,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -23210,111 +23265,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Restituisce il seno del parametro."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24762,9 +24953,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24821,7 +25017,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -26558,6 +26756,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Restituisce il seno del parametro."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30586,7 +30873,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -34488,7 +34775,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34502,7 +34789,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34727,7 +35015,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35719,7 +36007,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35791,9 +36079,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35884,12 +36172,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35915,13 +36197,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36275,7 +36550,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -39437,6 +39712,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -41203,6 +41481,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -41323,6 +41605,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45793,7 +46079,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -46556,6 +46844,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -49160,9 +49460,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -52512,6 +52810,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -53280,6 +53584,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53987,7 +54301,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54186,7 +54500,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -55324,13 +55638,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61832,7 +62146,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62955,8 +63271,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Calcola il prodotto vettoriale di questo vettore e [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/ja.po b/doc/translations/ja.po
index bf6d51175e..4c8cf54ae5 100644
--- a/doc/translations/ja.po
+++ b/doc/translations/ja.po
@@ -3559,8 +3559,13 @@ msgid "Gamepad button 22."
msgstr "ゲームパッド ボタン2。"
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "サãƒãƒ¼ãƒˆã•れるジョイスティック ãƒœã‚¿ãƒ³ã®æœ€å¤§æ•°ã‚’表ã™ã€‚"
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4666,8 +4671,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -11677,15 +11680,19 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr "enum [enum FFT_Size] ã®ã‚µã‚¤ã‚ºã‚’表ã—ã¾ã™ã€‚"
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+#, fuzzy
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr "音をマイクã§éŒ²éŸ³ã™ã‚‹éš›ã«ä½¿ç”¨ã™ã‚‹ã‚ªãƒ¼ãƒ‡ã‚£ã‚ªã‚¨ãƒ•ェクト。"
#: doc/classes/AudioEffectRecord.xml
+#, fuzzy
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
"ユーザーãŒéŸ³ã‚’マイクã§éŒ²éŸ³ã§ãるよã†ã«ã—ã¾ã™ã€‚録音ã•れるオーディオファイルã®"
"フォーマットを設定ã—ã€å–å¾—ã§ãã¾ã™ (8 bitã€16 bitã€åœ§ç¸®)。録音中ã§ã‚ã‚‹ã‹ã©ã†"
@@ -18189,9 +18196,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -18204,20 +18210,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"[code]name[/code] ã¨ã„ã†åå‰ã§æŒ‡å®šã—ãŸè¨­å®šãŒå­˜åœ¨ã™ã‚‹å ´åˆã¯ [code]true[/"
+"code]ã€ãã†ã§ãªã„å ´åˆã¯ [code]false[/code] ã‚’è¿”ã—ã¾ã™ã€‚"
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -18225,8 +18235,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -18234,16 +18246,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -18626,6 +18642,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "キーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "キーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "キーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "キーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "インデックス [code]index[/code] ã®ãƒã‚¹ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "キーå [code]name[/code] ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -19115,7 +19164,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -24975,111 +25032,251 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "テクスãƒãƒ£ã®ç¾åœ¨è¡¨ç¤ºã•れã¦ã„るフレームを設定ã—ã¾ã™ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "ã“ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã®ãƒ–レンドシェイプã®åå‰ã‚’è¿”ã—ã¾ã™ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "インデックスã«ã‚ˆã‚Šé…列ã‹ã‚‰è¦ç´ ã‚’削除ã—ã¾ã™ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "ディテールテクスãƒãƒ£ã¨å…±ã« [code]UV[/code] を使用ã—ã¾ã™ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "エディタ内ã§ãƒ—ロパティをグループ化ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã—ã¾ã™ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -26538,9 +26735,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -26597,7 +26799,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -28347,6 +28551,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "円柱ã®ãƒ¬ãƒ³ãƒ€ãƒªãƒ³ã‚°ã«ä½¿ã†ãƒžãƒ†ãƒªã‚¢ãƒ«ã€‚"
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -32393,7 +32686,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -36332,7 +36625,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -36346,7 +36639,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -36568,13 +36862,20 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]."
msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
+#, fuzzy
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
msgstr ""
+"ディテールオーãƒãƒ¼ãƒ¬ã‚¤ã®ãƒ”クセルã”ã¨ã®æ³•線を指定ã™ã‚‹ãƒ†ã‚¯ã‚¹ãƒãƒ£ã§ã™ã€‚\n"
+"[b]注:[/b] Godotã¯ã€æ³•線マップãŒX+ã€Y-ã€ãŠã‚ˆã³Z+ã®åº§æ¨™ã‚’使用ã™ã‚‹ã“ã¨ã‚’期待ã—"
+"ã¦ã„ã¾ã™ã€‚一般的ãªã‚¨ãƒ³ã‚¸ãƒ³ã«ã¦æœŸå¾…ã•ã‚Œã‚‹æ³•ç·šãƒžãƒƒãƒ—åº§æ¨™ã®æ¯”較ã¯ã€[url=http://"
+"wiki.polycount.com/wiki/"
+"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]ã“ã®ãƒšãƒ¼ã‚¸[/url] ã‚’å‚"
+"ç…§ã—ã¦ãã ã•ã„。"
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
@@ -37569,7 +37870,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -37644,9 +37945,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -37739,12 +38040,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -37771,13 +38066,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -38136,7 +38424,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -41301,6 +41589,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -43080,6 +43371,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -43200,6 +43495,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -47693,7 +47992,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -48470,6 +48771,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -51085,9 +51398,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"AABBã¯ä½ç½®ã€å¤§ãã•ã€ãŠã‚ˆã³ã„ãã¤ã‹ã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£é–¢æ•°ã‹ã‚‰ãªã‚Šã¾ã™ã€‚主ã«é«˜é€Ÿ"
"ãªã‚ªãƒ¼ãƒãƒ¼ãƒ©ãƒƒãƒ—検出ã«ä½¿ç”¨ã•れã¾ã™ã€‚"
@@ -54451,6 +54762,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -55219,6 +55536,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -55985,9 +56312,10 @@ msgstr ""
"ãŸã‚ã«ä½¿ç”¨ã•れるテクスãƒãƒ£ã§ã™ã€‚"
#: doc/classes/SpatialMaterial.xml
+#, fuzzy
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -56246,7 +56574,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -57548,13 +57876,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -64115,7 +64443,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -65225,8 +65555,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "ã“ã®ãƒ™ã‚¯ãƒˆãƒ«ã¨ [code]with[/code] ã®ã‚¯ãƒ­ã‚¹ç©ã‚’è¿”ã—ã¾ã™ã€‚"
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/ko.po b/doc/translations/ko.po
index 7e7d886ea0..5e79cdef11 100644
--- a/doc/translations/ko.po
+++ b/doc/translations/ko.po
@@ -2871,7 +2871,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3865,8 +3870,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9468,15 +9471,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15618,9 +15623,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15636,17 +15640,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15654,8 +15659,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15663,16 +15670,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16031,6 +16042,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16517,7 +16561,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22366,111 +22418,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23917,9 +24105,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23976,7 +24169,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25705,6 +25900,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29722,7 +30006,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33619,7 +33903,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33633,7 +33917,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33857,7 +34142,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34846,7 +35131,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34915,9 +35200,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35008,12 +35293,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35039,13 +35318,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35395,7 +35667,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38674,6 +38946,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40423,6 +40698,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40543,6 +40822,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45010,7 +45293,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45773,6 +46058,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48371,9 +48668,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51719,6 +52014,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52485,6 +52786,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53191,7 +53502,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53389,7 +53700,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54523,13 +54834,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60992,7 +61303,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62097,7 +62410,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/lv.po b/doc/translations/lv.po
index 7fd77a6adc..b560b54e69 100644
--- a/doc/translations/lv.po
+++ b/doc/translations/lv.po
@@ -2759,7 +2759,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3753,8 +3758,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9353,15 +9356,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15468,9 +15473,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15486,17 +15490,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15504,8 +15509,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15513,16 +15520,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15882,6 +15893,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16367,7 +16405,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22151,111 +22197,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23701,9 +23882,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23760,7 +23946,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25489,6 +25677,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29497,7 +29773,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33391,7 +33667,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33405,7 +33681,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33629,7 +33906,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34600,7 +34877,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34668,9 +34945,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34762,12 +35039,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34791,13 +35062,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35145,7 +35409,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38295,6 +38559,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40027,6 +40294,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40147,6 +40418,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44607,7 +44882,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45370,6 +45647,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47968,9 +48257,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51316,6 +51603,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52082,6 +52375,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52788,7 +53091,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52986,7 +53289,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54120,13 +54423,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60581,7 +60884,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61686,7 +61991,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/mr.po b/doc/translations/mr.po
index da3c6ecbe3..69aaa02fc5 100644
--- a/doc/translations/mr.po
+++ b/doc/translations/mr.po
@@ -2742,7 +2742,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3736,8 +3741,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9317,15 +9320,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15392,9 +15397,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15410,17 +15414,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15428,8 +15433,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15437,16 +15444,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15806,6 +15817,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16291,7 +16329,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22049,111 +22095,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23593,9 +23774,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23652,7 +23838,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25372,6 +25560,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29361,7 +29637,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33233,7 +33509,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33247,7 +33523,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33471,7 +33748,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34428,7 +34705,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34496,9 +34773,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34590,12 +34867,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34619,13 +34890,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34973,7 +35237,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38105,6 +38369,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39835,6 +40102,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39952,6 +40223,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44409,7 +44684,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45172,6 +45449,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47765,9 +48054,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51100,6 +51387,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51862,6 +52155,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52559,7 +52862,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52757,7 +53060,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53891,13 +54194,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60340,7 +60643,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61443,7 +61748,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/nb.po b/doc/translations/nb.po
index 2b78a146f1..395ddd5a2f 100644
--- a/doc/translations/nb.po
+++ b/doc/translations/nb.po
@@ -5,20 +5,21 @@
#
# slasken06 <ask.skivdal@gmail.com>, 2021.
# Daniel Skogly <daniel@klungo.no>, 2021.
+# Imre Kristoffer Eilertsen <imreeil42@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2021-11-03 13:15+0000\n"
-"Last-Translator: Daniel Skogly <daniel@klungo.no>\n"
+"PO-Revision-Date: 2022-01-10 13:19+0000\n"
+"Last-Translator: Imre Kristoffer Eilertsen <imreeil42@gmail.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot-class-reference/nb_NO/>\n"
-"Language: nb_NO\n"
+"Language: nb\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.9-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: doc/tools/make_rst.py
msgid "Description"
@@ -26,7 +27,7 @@ msgstr "Beskrivelse"
#: doc/tools/make_rst.py
msgid "Tutorials"
-msgstr ""
+msgstr "Opplæring"
#: doc/tools/make_rst.py
msgid "Properties"
@@ -78,19 +79,19 @@ msgstr ""
#: doc/tools/make_rst.py
msgid "Default"
-msgstr ""
+msgstr "Standard"
#: doc/tools/make_rst.py
msgid "Setter"
-msgstr ""
+msgstr "Setter"
#: doc/tools/make_rst.py
msgid "value"
-msgstr ""
+msgstr "verdi"
#: doc/tools/make_rst.py
msgid "Getter"
-msgstr ""
+msgstr "Henter"
#: doc/tools/make_rst.py
msgid ""
@@ -2752,7 +2753,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3746,8 +3752,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9327,15 +9331,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15402,9 +15408,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15420,17 +15425,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15438,8 +15444,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15447,16 +15455,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15816,6 +15828,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16301,7 +16340,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22059,111 +22106,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23603,9 +23785,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23662,7 +23849,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25382,6 +25571,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29371,7 +29648,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33243,7 +33520,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33257,7 +33534,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33481,7 +33759,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34438,7 +34716,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34506,9 +34784,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34600,12 +34878,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34629,13 +34901,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34983,7 +35248,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38115,6 +38380,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39845,6 +40113,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39962,6 +40234,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44419,7 +44695,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45182,6 +45460,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47775,9 +48065,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51110,6 +51398,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51872,6 +52166,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52569,7 +52873,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52767,7 +53071,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53901,13 +54205,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60350,7 +60654,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61140,11 +61446,11 @@ msgstr ""
#: modules/upnp/doc_classes/UPNP.xml
msgid "Invalid parameter."
-msgstr ""
+msgstr "Ugyldig parameter."
#: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml
msgid "HTTP error."
-msgstr ""
+msgstr "HTTP feil."
#: modules/upnp/doc_classes/UPNP.xml
msgid "Socket error."
@@ -61168,7 +61474,7 @@ msgstr ""
#: modules/upnp/doc_classes/UPNP.xml modules/upnp/doc_classes/UPNPDevice.xml
msgid "Unknown error."
-msgstr ""
+msgstr "Ukjent feil."
#: modules/upnp/doc_classes/UPNPDevice.xml
msgid "UPNP device."
@@ -61453,7 +61759,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/ne.po b/doc/translations/ne.po
index 2c380d647b..1d93069025 100644
--- a/doc/translations/ne.po
+++ b/doc/translations/ne.po
@@ -2742,7 +2742,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3736,8 +3741,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9317,15 +9320,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15392,9 +15397,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15410,17 +15414,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15428,8 +15433,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15437,16 +15444,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15806,6 +15817,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16291,7 +16329,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22049,111 +22095,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23593,9 +23774,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23652,7 +23838,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25372,6 +25560,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29361,7 +29637,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33233,7 +33509,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33247,7 +33523,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33471,7 +33748,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34428,7 +34705,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34496,9 +34773,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34590,12 +34867,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34619,13 +34890,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34973,7 +35237,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38105,6 +38369,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39835,6 +40102,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39952,6 +40223,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44409,7 +44684,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45172,6 +45449,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47765,9 +48054,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51100,6 +51387,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51862,6 +52155,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52559,7 +52862,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52757,7 +53060,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53891,13 +54194,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60340,7 +60643,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61443,7 +61748,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/nl.po b/doc/translations/nl.po
index f3b757ffba..cc577df882 100644
--- a/doc/translations/nl.po
+++ b/doc/translations/nl.po
@@ -2793,7 +2793,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3787,8 +3792,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9387,15 +9390,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15502,9 +15507,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15520,17 +15524,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15538,8 +15543,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15547,16 +15554,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15916,6 +15927,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16401,7 +16439,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22185,111 +22231,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23735,9 +23916,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23794,7 +23980,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25523,6 +25711,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29531,7 +29807,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33425,7 +33701,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33439,7 +33715,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33663,7 +33940,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34634,7 +34911,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34702,9 +34979,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34796,12 +35073,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34825,13 +35096,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35179,7 +35443,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38329,6 +38593,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40061,6 +40328,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40181,6 +40452,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44641,7 +44916,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45404,6 +45681,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48002,9 +48291,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51351,6 +51638,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52117,6 +52410,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52823,7 +53126,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53021,7 +53324,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54155,13 +54458,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60616,7 +60919,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61721,7 +62026,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/pl.po b/doc/translations/pl.po
index 460b6640f5..34ad88e7af 100644
--- a/doc/translations/pl.po
+++ b/doc/translations/pl.po
@@ -3210,7 +3210,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4204,8 +4209,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9813,15 +9816,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15945,9 +15950,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15963,17 +15967,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15981,8 +15986,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15990,16 +15997,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16358,6 +16369,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16844,7 +16888,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22638,111 +22690,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Zwraca sinus parametru."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24189,9 +24377,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24248,7 +24441,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25981,6 +26176,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Zwraca sinus parametru."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30001,7 +30285,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33907,7 +34191,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33921,7 +34205,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34145,7 +34430,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35141,7 +35426,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35216,9 +35501,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35309,12 +35594,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35340,13 +35619,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35700,7 +35972,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38856,6 +39128,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40620,6 +40895,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40740,6 +41019,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45209,7 +45492,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45972,6 +46257,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48578,9 +48875,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51929,6 +52224,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52696,6 +52997,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53402,7 +53713,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53600,7 +53911,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54737,13 +55048,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61216,7 +61527,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62321,8 +62634,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Liczy iloczyn wektorowy tego wektora oraz [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/pt.po b/doc/translations/pt.po
index b11d10ee96..4452a8e461 100644
--- a/doc/translations/pt.po
+++ b/doc/translations/pt.po
@@ -3497,8 +3497,13 @@ msgid "Gamepad button 22."
msgstr "Botão 22 do controle."
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Representa a quantidade máxima de botões de joystick suportados."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4501,8 +4506,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10094,15 +10097,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -16207,9 +16212,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -16225,17 +16229,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -16243,8 +16248,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -16252,16 +16259,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16620,6 +16631,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -17108,7 +17152,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22872,111 +22924,252 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Discards the changes made in file present at [code]file_path[/code]."
+msgstr "Salva a cena como um ficheiro em [code]path[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a branch from the local VCS."
+msgstr "Remove todos os pontos da linha."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "Remove todos os itens da lista."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "Salva a cena como um ficheiro em [code]path[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A new file has been added."
+msgstr "Emitido quando uma nova interface é adicionada."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24416,9 +24609,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24475,7 +24673,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -26195,6 +26395,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "A largura de uma textura."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30184,7 +30473,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -34060,7 +34349,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34074,7 +34363,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34298,7 +34588,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35268,7 +35558,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35338,9 +35628,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35434,12 +35724,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -35463,13 +35747,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35820,7 +36097,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38954,6 +39231,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40686,6 +40966,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40803,6 +41087,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45260,7 +45548,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -46023,6 +46313,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48616,9 +48918,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51953,6 +52253,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52716,6 +53022,17 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "Emitido quando um ficheiro é selecionado."
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53413,7 +53730,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53615,7 +53932,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54763,13 +55080,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61217,7 +61534,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62320,8 +62639,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Retorna o produto cruzado deste vetor e [code]com[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/pt_BR.po b/doc/translations/pt_BR.po
index aa55ec1a2f..00f49e35c1 100644
--- a/doc/translations/pt_BR.po
+++ b/doc/translations/pt_BR.po
@@ -3646,8 +3646,13 @@ msgid "Gamepad button 22."
msgstr "Botão 22 do controle."
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Representa o número máximo de botões de joystick suportados."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4727,8 +4732,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10350,15 +10353,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -16529,9 +16534,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -16547,17 +16551,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -16565,8 +16570,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -16574,16 +16581,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16942,6 +16953,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -17430,7 +17474,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -23227,111 +23279,252 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Discards the changes made in file present at [code]file_path[/code]."
+msgstr "Salva a cena como um arquivo em [code]path[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Retorna o nome do nó em [code]idx[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a branch from the local VCS."
+msgstr "Remove todos os pontos da linha."
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "Remove todos os itens da lista."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "Salva a cena como um arquivo em [code]path[/code]."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A new file has been added."
+msgstr "Emitido quando uma nova interface é adicionada."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24779,9 +24972,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24838,7 +25036,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -26571,6 +26771,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "A largura de uma textura."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30605,7 +30894,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -34513,7 +34802,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34527,7 +34816,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34751,7 +35041,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35743,7 +36033,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35815,9 +36105,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35910,12 +36200,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35941,13 +36225,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -36304,7 +36581,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -39456,6 +39733,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -41223,6 +41503,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -41343,6 +41627,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45815,7 +46103,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -46578,6 +46868,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -49182,9 +49484,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -52531,6 +52831,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -53301,6 +53607,17 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "Emitido quando um arquivo é selecionado."
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -54008,7 +54325,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54210,7 +54527,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -55361,13 +55678,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61856,7 +62173,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62960,8 +63279,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Retorna o produto cruzado deste vetor e [code]com[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/ro.po b/doc/translations/ro.po
index 11b2ac9b13..2d61f987eb 100644
--- a/doc/translations/ro.po
+++ b/doc/translations/ro.po
@@ -2762,7 +2762,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3756,8 +3761,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9356,15 +9359,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15471,9 +15476,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15489,17 +15493,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15507,8 +15512,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15516,16 +15523,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15885,6 +15896,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16370,7 +16408,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22154,111 +22200,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23704,9 +23885,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23763,7 +23949,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25492,6 +25680,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29500,7 +29776,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33394,7 +33670,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33408,7 +33684,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33632,7 +33909,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34603,7 +34880,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34671,9 +34948,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34765,12 +35042,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34794,13 +35065,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35148,7 +35412,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38298,6 +38562,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40030,6 +40297,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40150,6 +40421,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44610,7 +44885,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45373,6 +45650,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47971,9 +48260,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51319,6 +51606,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52085,6 +52378,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52791,7 +53094,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52989,7 +53292,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54123,13 +54426,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60584,7 +60887,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61689,7 +61994,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/ru.po b/doc/translations/ru.po
index 8c22c1edf5..6bfd3b83b6 100644
--- a/doc/translations/ru.po
+++ b/doc/translations/ru.po
@@ -3740,9 +3740,13 @@ msgid "Gamepad button 22."
msgstr "Кнопка 22 геймпада."
#: doc/classes/@GlobalScope.xml
-#, fuzzy
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "МакÑимальное чиÑло кнопок игрового контроллера."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -4865,8 +4869,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10956,15 +10958,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -17177,9 +17181,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -17192,20 +17195,24 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
+"Возвращает [code]true[/code] еÑли [code]a[/code] и [code]b[/code] "
+"приблизительно равны друг другу."
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -17213,8 +17220,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -17222,16 +17231,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -17617,6 +17630,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -18105,7 +18151,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -23914,111 +23968,250 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid ""
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "УÑтанавливает текущий видимый кадр текÑтуры."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Возвращает ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "УдалÑет Ñлемент из маÑÑива по индекÑу."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "ИÑпользуетÑÑ Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²ÐºÐ¸ ÑвойÑтв в редакторе."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -25468,9 +25661,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25527,7 +25725,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -27262,6 +27462,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Цвет Ñффекта отражениÑ."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -31286,7 +31575,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -35213,7 +35502,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -35227,7 +35516,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -35451,7 +35741,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -36447,7 +36737,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -36519,9 +36809,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -36613,12 +36903,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -36644,13 +36928,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -37004,7 +37281,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -40171,6 +40448,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -41940,6 +42220,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -42060,6 +42344,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -46556,7 +46844,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -47323,6 +47613,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -49971,9 +50273,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"AABB ÑоÑтоит из позиции, размера и неÑкольких вÑпомогательных функций. "
"Обычно иÑпользуетÑÑ Ð´Ð»Ñ Ð±Ñ‹Ñтрых теÑтов на перекрытие."
@@ -53327,6 +53627,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -54094,6 +54400,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -54806,7 +55122,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -55007,7 +55323,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -56143,18 +56459,26 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
+#, fuzzy
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
"code] will make it so the [code]run[/code] animation uses the normal map."
msgstr ""
+"ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ ÑоздаетÑÑ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ реÑурÑа [SpriteFrames], который можно наÑтроить "
+"в редакторе Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ панели SpriteFrames.\n"
+"[b]Примечание:[/b] Ð’Ñ‹ можете ÑвÑзать набор карт нормалей, Ñоздав "
+"дополнительные реÑурÑÑ‹ [SpriteFrames] Ñ ÑуффикÑом [code]_normal[/code]. "
+"Ðапример, наличие двух реÑурÑов [SpriteFrames] [code]run[/code] и "
+"[code]run_normal[/code] Ñделает так, что Ð°Ð½Ð¸Ð¼Ð°Ñ†Ð¸Ñ [code]run[/code] будет "
+"иÑпользовать карту нормалей."
#: doc/classes/SpriteFrames.xml
msgid "Adds a new animation to the library."
@@ -62684,7 +63008,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -63809,9 +64135,17 @@ msgstr ""
"length()[/code]."
#: doc/classes/Vector2.xml
-#, fuzzy
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "Возвращает ÑкалÑрное произведение Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð¾Ð¼ [code]b[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
#, fuzzy
diff --git a/doc/translations/sk.po b/doc/translations/sk.po
index 9d36ee690b..1939f0226d 100644
--- a/doc/translations/sk.po
+++ b/doc/translations/sk.po
@@ -2745,7 +2745,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3739,8 +3744,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9339,15 +9342,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15454,9 +15459,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15472,17 +15476,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15490,8 +15495,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15499,16 +15506,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15868,6 +15879,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16353,7 +16391,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22137,111 +22183,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23687,9 +23868,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23746,7 +23932,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25475,6 +25663,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29483,7 +29759,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33377,7 +33653,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33391,7 +33667,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33615,7 +33892,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34586,7 +34863,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34654,9 +34931,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34748,12 +35025,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34777,13 +35048,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35131,7 +35395,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38281,6 +38545,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40013,6 +40280,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40133,6 +40404,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44593,7 +44868,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45356,6 +45633,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47954,9 +48243,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51302,6 +51589,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52068,6 +52361,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52774,7 +53077,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52972,7 +53275,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54106,13 +54409,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60567,7 +60870,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61672,7 +61977,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/sr_Cyrl.po b/doc/translations/sr_Cyrl.po
index 7330ba9f1f..7dd34a8986 100644
--- a/doc/translations/sr_Cyrl.po
+++ b/doc/translations/sr_Cyrl.po
@@ -2756,7 +2756,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3750,8 +3755,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9350,15 +9353,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15465,9 +15470,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15483,17 +15487,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15501,8 +15506,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15510,16 +15517,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15879,6 +15890,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16364,7 +16402,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22148,111 +22194,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23698,9 +23879,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23757,7 +23943,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25486,6 +25674,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29494,7 +29770,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33388,7 +33664,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33402,7 +33678,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33626,7 +33903,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34597,7 +34874,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34665,9 +34942,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34759,12 +35036,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34788,13 +35059,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35142,7 +35406,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38292,6 +38556,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40024,6 +40291,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40144,6 +40415,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44604,7 +44879,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45367,6 +45644,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47965,9 +48254,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51313,6 +51600,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52079,6 +52372,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52785,7 +53088,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52983,7 +53286,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54117,13 +54420,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60578,7 +60881,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61683,7 +61988,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/sv.po b/doc/translations/sv.po
index bb965079c5..c665310546 100644
--- a/doc/translations/sv.po
+++ b/doc/translations/sv.po
@@ -2745,7 +2745,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3739,8 +3744,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9320,15 +9323,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15395,9 +15400,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15413,17 +15417,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15431,8 +15436,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15440,16 +15447,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15809,6 +15820,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16294,7 +16332,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22052,111 +22098,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23596,9 +23777,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23655,7 +23841,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25375,6 +25563,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29364,7 +29640,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33236,7 +33512,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33250,7 +33526,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33474,7 +33751,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34431,7 +34708,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34499,9 +34776,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34593,12 +34870,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34622,13 +34893,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -34976,7 +35240,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38108,6 +38372,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39838,6 +40105,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -39955,6 +40226,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44412,7 +44687,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45175,6 +45452,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47768,9 +48057,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51103,6 +51390,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51865,6 +52158,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52562,7 +52865,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52760,7 +53063,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53894,13 +54197,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60343,7 +60646,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61446,7 +61751,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/th.po b/doc/translations/th.po
index ca9954ed1c..c71cda4def 100644
--- a/doc/translations/th.po
+++ b/doc/translations/th.po
@@ -2838,7 +2838,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3839,8 +3844,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9441,15 +9444,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15558,9 +15563,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15576,17 +15580,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15594,8 +15599,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15603,16 +15610,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15972,6 +15983,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16457,7 +16495,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22241,111 +22287,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "คืนค่าผà¸à¸œà¸±à¸™à¸£à¸¹à¸—สองของพารามิเตอร์"
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23791,9 +23973,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23850,7 +24037,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25579,6 +25768,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "คืนค่า arc tanh ของพารามิเตอร์"
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29597,7 +29875,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33502,7 +33780,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33516,7 +33794,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33740,7 +34019,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34718,7 +34997,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34786,9 +35065,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34880,12 +35159,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34909,13 +35182,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35263,7 +35529,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38445,6 +38711,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40180,6 +40449,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40300,6 +40573,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44764,7 +45041,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45527,6 +45806,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48130,9 +48421,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51478,6 +51767,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52244,6 +52539,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52950,7 +53255,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53148,7 +53453,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54283,13 +54588,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60746,7 +61051,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61857,7 +62164,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/tl.po b/doc/translations/tl.po
index e7155eb8d5..a30b704472 100644
--- a/doc/translations/tl.po
+++ b/doc/translations/tl.po
@@ -2817,8 +2817,13 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "Kumakatawan sa pinakamaraming bilang ng joystick na sinusuportahan."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -3811,8 +3816,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9392,15 +9395,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15470,9 +15475,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15488,17 +15492,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15506,8 +15511,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15515,16 +15522,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15884,6 +15895,33 @@ msgstr ""
#: doc/classes/Control.xml
msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr ""
+
+#: doc/classes/Control.xml
+msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
"anchor_bottom], [member anchor_left], [member anchor_right] and [member "
@@ -16369,7 +16407,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22127,111 +22173,246 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Returns the name of the underlying VCS provider."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23671,9 +23852,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23730,7 +23916,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25450,6 +25638,94 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The [Gradient] used to fill the texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29439,7 +29715,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33311,7 +33587,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33325,7 +33601,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33549,7 +33826,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34512,7 +34789,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34580,9 +34857,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34674,12 +34951,6 @@ msgstr ""
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
msgstr ""
@@ -34703,13 +34974,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35057,7 +35321,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38189,6 +38453,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -39919,6 +40186,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40036,6 +40307,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44493,7 +44768,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45256,6 +45533,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -47849,9 +48138,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51184,6 +51471,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -51946,6 +52239,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52643,7 +52946,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -52841,7 +53144,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53975,13 +54278,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60427,7 +60730,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61530,7 +61835,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/tr.po b/doc/translations/tr.po
index 213c6cb98a..31c0cd045f 100644
--- a/doc/translations/tr.po
+++ b/doc/translations/tr.po
@@ -3516,7 +3516,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4510,8 +4515,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -10112,15 +10115,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -16242,9 +16247,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -16260,17 +16264,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -16278,8 +16283,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -16287,16 +16294,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16655,6 +16666,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -17141,7 +17185,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22931,111 +22983,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24486,9 +24674,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24545,7 +24738,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -26276,6 +26471,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Verilen değerin sinüsünü döndürür."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -30289,7 +30573,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -34187,7 +34471,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34201,7 +34485,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -34425,7 +34710,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -35417,7 +35702,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -35486,9 +35771,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35579,12 +35864,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35610,13 +35889,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35969,7 +36241,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -39122,6 +39394,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40879,6 +41154,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40999,6 +41278,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -45468,7 +45751,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -46231,6 +46516,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48836,9 +49133,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -52184,6 +52479,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52950,6 +53251,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53656,7 +53967,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53854,7 +54165,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54990,13 +55301,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -61461,7 +61772,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62566,7 +62879,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/uk.po b/doc/translations/uk.po
index 41495f384a..c4a4cdbaf5 100644
--- a/doc/translations/uk.po
+++ b/doc/translations/uk.po
@@ -2869,7 +2869,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3863,8 +3868,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9471,15 +9474,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15594,9 +15599,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15612,17 +15616,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15630,8 +15635,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15639,16 +15646,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16007,6 +16018,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16493,7 +16537,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22281,111 +22333,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23832,9 +24020,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23891,7 +24084,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25621,6 +25816,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29637,7 +29921,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33534,7 +33818,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33548,7 +33832,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33772,7 +34057,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34763,7 +35048,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34832,9 +35117,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34925,12 +35210,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -34956,13 +35235,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35312,7 +35584,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38465,6 +38737,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40216,6 +40491,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40336,6 +40615,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44803,7 +45086,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45566,6 +45851,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48164,9 +48461,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51512,6 +51807,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52279,6 +52580,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52985,7 +53296,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53183,7 +53494,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54318,13 +54629,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60789,7 +61100,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61894,8 +62207,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "ОбчиÑлює векторний добуток двох векторів та [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/doc/translations/vi.po b/doc/translations/vi.po
index b0fe535eca..f6621f3c4b 100644
--- a/doc/translations/vi.po
+++ b/doc/translations/vi.po
@@ -3169,7 +3169,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -4174,8 +4179,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9772,15 +9775,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15857,9 +15862,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15875,17 +15879,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15893,8 +15898,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15902,16 +15909,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -16270,6 +16281,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16756,7 +16800,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22520,111 +22572,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -24067,9 +24255,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -24126,7 +24319,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25846,6 +26041,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "Trả vỠsin của tham số."
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29840,7 +30124,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33715,7 +33999,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33729,7 +34013,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33953,7 +34238,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34929,7 +35214,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34999,9 +35284,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -35092,12 +35377,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -35123,13 +35402,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35481,7 +35753,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38616,6 +38888,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40369,6 +40644,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40486,6 +40765,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44955,7 +45238,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45720,6 +46005,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48318,9 +48615,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51653,6 +51948,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52415,6 +52716,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -53114,7 +53425,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53313,7 +53624,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54448,13 +54759,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60911,7 +61222,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -62014,7 +62327,16 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
msgstr ""
#: doc/classes/Vector2.xml
diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po
index e65d84756e..94f4b4d5da 100644
--- a/doc/translations/zh_CN.po
+++ b/doc/translations/zh_CN.po
@@ -61,7 +61,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"PO-Revision-Date: 2022-01-07 07:07+0000\n"
+"PO-Revision-Date: 2022-01-12 16:56+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot-class-reference/zh_Hans/>\n"
@@ -113,69 +113,68 @@ msgid "Method Descriptions"
msgstr "方法说明"
#: doc/tools/make_rst.py
-#, fuzzy
msgid "Theme Property Descriptions"
-msgstr "属性说明"
+msgstr "主题属性说明"
#: doc/tools/make_rst.py
msgid "Inherits:"
-msgstr ""
+msgstr "继承:"
#: doc/tools/make_rst.py
msgid "Inherited By:"
-msgstr ""
+msgstr "派生:"
#: doc/tools/make_rst.py
msgid "(overrides %s)"
-msgstr ""
+msgstr "(覆盖 %s)"
#: doc/tools/make_rst.py
msgid "Default"
-msgstr ""
+msgstr "默认"
#: doc/tools/make_rst.py
msgid "Setter"
-msgstr ""
+msgstr "Setter"
#: doc/tools/make_rst.py
msgid "value"
-msgstr ""
+msgstr "值"
#: doc/tools/make_rst.py
msgid "Getter"
-msgstr ""
+msgstr "Getter"
#: doc/tools/make_rst.py
msgid ""
"This method should typically be overridden by the user to have any effect."
-msgstr ""
+msgstr "本方法通常需è¦ç”¨æˆ·è¦†ç›–æ‰èƒ½ç”Ÿæ•ˆã€‚"
#: doc/tools/make_rst.py
msgid ""
"This method has no side effects. It doesn't modify any of the instance's "
"member variables."
-msgstr ""
+msgstr "本方法没有副作用。ä¸ä¼šä¿®æ”¹è¯¥å®žä¾‹çš„任何æˆå‘˜å˜é‡ã€‚"
#: doc/tools/make_rst.py
msgid ""
"This method accepts any number of arguments after the ones described here."
-msgstr ""
+msgstr "本方法除了在此处æè¿°çš„傿•°å¤–,还能够继续接å—ä»»æ„æ•°é‡çš„傿•°ã€‚"
#: doc/tools/make_rst.py
msgid "This method is used to construct a type."
-msgstr ""
+msgstr "本方法用于构造æŸä¸ªç±»åž‹ã€‚"
#: doc/tools/make_rst.py
msgid ""
"This method doesn't need an instance to be called, so it can be called "
"directly using the class name."
-msgstr ""
+msgstr "调用本方法无需实例,所以å¯ä»¥ç›´æŽ¥ä½¿ç”¨ç±»å调用。"
#: doc/tools/make_rst.py
msgid ""
"This method describes a valid operator to use with this type as left-hand "
"operand."
-msgstr ""
+msgstr "本方法æè¿°çš„æ˜¯ä½¿ç”¨æœ¬ç±»åž‹ä½œä¸ºå·¦æ“作数的有效æ“作符。"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid "Built-in GDScript functions."
@@ -847,6 +846,20 @@ msgid ""
"[/codeblock]\n"
"See also [method lerp] which performs the reverse of this operation."
msgstr ""
+"返回æ’值或外推的因å­ã€‚范围用 [code]from[/code] å’Œ [code]to[/code] 指定,æ’值"
+"åŽçš„值用 [code]weight[/code] 指定。如果 [code]weight[/code] 在 [code]from[/"
+"code] å’Œ [code]to[/code] 之间(包å«ï¼‰ï¼Œé‚£ä¹ˆè¿”回的值在 [code]0.0[/code] å’Œ "
+"[code]1.0[/code] 之间。如果 [code]weight[/code] 在该范围之外,则返回的是外推"
+"å› å­ï¼ˆè¿”回值å°äºŽ [code]0.0[/code] 或大于 [code]1.0[/code])。\n"
+"[codeblock]\n"
+"# 下é¢çš„ `lerp()` 调用时的æ’值比例是 0.75。\n"
+"var middle = lerp(20, 30, 0.75)\n"
+"# `middle` 现在是 27.5。\n"
+"# 现在,我们å‡è£…忘记了原æ¥çš„æ¯”ä¾‹ï¼Œæƒ³è¦æ‰¾åˆ°æ˜¯å¤šå°‘。\n"
+"var ratio = inverse_lerp(20, 30, 27.5)\n"
+"# `ratio`现在是 0.75。\n"
+"[/codeblock]\n"
+"本æ“作的逆æ“作请å‚阅 [method lerp]。"
#: modules/gdscript/doc_classes/@GDScript.xml
msgid ""
@@ -908,7 +921,6 @@ msgstr ""
"[/codeblock]"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Linearly interpolates between two values by the factor defined in "
"[code]weight[/code]. To perform interpolation, [code]weight[/code] should be "
@@ -928,8 +940,9 @@ msgid ""
"To perform eased interpolation with [method lerp], combine it with [method "
"ease] or [method smoothstep]."
msgstr ""
-"用一个归一化的值在两个值之间进行线性æ’值。这是 [method inverse_lerp] 的逆è¿"
-"算。\n"
+"在两个值之间按照 [code]weight[/code] 定义的因数进行线性æ’值。进行æ’值时,"
+"[code]weight[/code] 应该在 [code]0.0[/code] 和 [code]1.0[/code] 之间(包"
+"å«ï¼‰ã€‚然而,在此区间外的值也是å…许的,å¯ç”¨äºŽæ‰§è¡Œ[i]外推[/i]。\n"
"如果 [code]from[/code] å’Œ [code]to[/code] 傿•°ç±»åž‹æ˜¯ [int] 或 [float],返回值"
"都是 [float]。\n"
"如果两者都是相åŒçš„å‘é‡ç±»åž‹ï¼ˆ[Vector2]ã€[Vector3]或[Color]),返回值将是相åŒçš„"
@@ -938,10 +951,11 @@ msgstr ""
"[codeblock]\n"
"lerp(0, 4, 0.75) # 返回 3.0\n"
"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # 返回 Vector2(2, 3.5)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"å¦è¯·å‚阅本æ“作的逆è¿ç®— [method inverse_lerp]ã€‚è¦æ‰§è¡Œç¼“动的 [method lerp] æ’"
+"值,请将其与 [method ease] 或 [method smoothstep] 组åˆã€‚"
#: modules/gdscript/doc_classes/@GDScript.xml
-#, fuzzy
msgid ""
"Linearly interpolates between two angles (in radians) by a normalized "
"value.\n"
@@ -959,8 +973,9 @@ msgid ""
"[/codeblock]"
msgstr ""
"通过归一化值在两个角度之间(以弧度为å•ä½ï¼‰è¿›è¡Œçº¿æ€§æ’值。\n"
-"与 [method lerp] 相似,但是当角度环绕 [constant @GDScript.TAU] 时会准确æ’"
-"值。\n"
+"与 [method lerp] 相似,但是当角度环绕 [constant @GDScript.TAU] 时会准确æ’值。"
+"è¦ä½¿ç”¨ [method lerp_angle] 执行缓动æ’值,请将其与 [method ease] 或 [method "
+"smoothstep] 组åˆã€‚\n"
"[codeblock]\n"
"extends Sprite\n"
"var elapsed = 0.0\n"
@@ -2235,7 +2250,7 @@ msgid ""
"[b]Note:[/b] Only implemented on Android."
msgstr ""
"[JavaClassWrapper] å•例。\n"
-"[b]注æ„:[/b] 仅在 Android 上实现。"
+"[b]注æ„:[/b]仅在 Android 上实现。"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -2243,26 +2258,23 @@ msgid ""
"[b]Note:[/b] Only implemented on HTML5."
msgstr ""
"[JavaScript] å•例。\n"
-"[b]注æ„:[/b] 仅在HTML5上实现。"
+"[b]注æ„:[/b]仅在 HTML5 上实现。"
#: doc/classes/@GlobalScope.xml
msgid "The [Marshalls] singleton."
msgstr "[Marshalls] å•例。"
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid "The [Navigation2DServer] singleton."
-msgstr "[TranslationServer]å•例。"
+msgstr "[Navigation2DServer] å•例。"
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid "The [NavigationMeshGenerator] singleton."
-msgstr "[EditorNavigationMeshGenerator] å•例。"
+msgstr "[NavigationMeshGenerator] å•例。"
#: doc/classes/@GlobalScope.xml
-#, fuzzy
msgid "The [NavigationServer] singleton."
-msgstr "[TranslationServer]å•例。"
+msgstr "[NavigationServer] å•例。"
#: doc/classes/@GlobalScope.xml
msgid "The [OS] singleton."
@@ -2286,7 +2298,7 @@ msgstr "[ProjectSettings] å•例。"
#: doc/classes/@GlobalScope.xml
msgid "The [ResourceLoader] singleton."
-msgstr "[ResourceLoader]å•例。"
+msgstr "[ResourceLoader] å•例。"
#: doc/classes/@GlobalScope.xml
msgid "The [ResourceSaver] singleton."
@@ -2298,7 +2310,7 @@ msgstr "[Time] å•例。"
#: doc/classes/@GlobalScope.xml
msgid "The [TranslationServer] singleton."
-msgstr "[TranslationServer]å•例。"
+msgstr "[TranslationServer] å•例。"
#: doc/classes/@GlobalScope.xml
msgid "The [VisualScriptEditor] singleton."
@@ -3543,8 +3555,13 @@ msgid "Gamepad button 22."
msgstr "æ¸¸æˆæ‰‹æŸ„按钮22。"
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
-msgstr "代表支æŒçš„æ“çºµæ†æŒ‰é’®çš„æœ€å¤§æ•°é‡ã€‚"
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
+msgstr ""
#: doc/classes/@GlobalScope.xml
msgid "DualShock circle button."
@@ -3779,30 +3796,34 @@ msgid ""
"MIDI note OFF message. See the documentation of [InputEventMIDI] for "
"information of how to use MIDI inputs."
msgstr ""
+"MIDI 音符 OFF 消æ¯ã€‚如何使用 MIDI 输入的信æ¯è¯·å‚阅 [InputEventMIDI] 的文档。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI note ON message. See the documentation of [InputEventMIDI] for "
"information of how to use MIDI inputs."
msgstr ""
+"MIDI 音符 ON 消æ¯ã€‚如何使用 MIDI 输入的信æ¯è¯·å‚阅 [InputEventMIDI] 的文档。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI aftertouch message. This message is most often sent by pressing down on "
"the key after it \"bottoms out\"."
-msgstr ""
+msgstr "MIDI è§¦åŽæ¶ˆæ¯ã€‚这个消æ¯ç»å¸¸éƒ½æ˜¯åœ¨æŒ‰é”®â€œç»“æŸâ€åŽç»§ç»­æ–½åŽ‹æ—¶å‘é€ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI control change message. This message is sent when a controller value "
"changes. Controllers include devices such as pedals and levers."
msgstr ""
+"MIDI 控制å˜åŒ–消æ¯ã€‚这个消æ¯ä¼šåœ¨æŽ§åˆ¶å™¨å€¼å‘生å˜åŒ–æ—¶å‘é€ã€‚æŽ§åˆ¶å™¨åŒ…æ‹¬è¸æ¿ã€æŽ¨æ†ç­‰"
+"设备。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI program change message. This message sent when the program patch number "
"changes."
-msgstr ""
+msgstr "MIDI 音色å˜åŒ–消æ¯ã€‚这个消æ¯ä¼šåœ¨éŸ³è‰² Patch å·å˜åŒ–æ—¶å‘é€ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -3810,74 +3831,83 @@ msgid ""
"down on the key after it \"bottoms out\". This message is different from "
"polyphonic after-touch as it indicates the highest pressure across all keys."
msgstr ""
+"MIDI 通é“压力消æ¯ã€‚这个消æ¯ç»å¸¸éƒ½æ˜¯åœ¨æŒ‰é”®â€œç»“æŸâ€åŽç»§ç»­æ–½åŽ‹æ—¶å‘é€ã€‚这个消æ¯ä¸Žå¤"
+"音触åŽä¸åŒï¼Œå› ä¸ºå®ƒè¡¨ç¤ºçš„æ˜¯æ‰€æœ‰é”®ä¸­çš„æœ€å¤§åŽ‹åŠ›ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI pitch bend message. This message is sent to indicate a change in the "
"pitch bender (wheel or lever, typically)."
msgstr ""
+"MIDI 弯音消æ¯ã€‚å‘é€è¿™ä¸ªæ¶ˆæ¯è¡¨ç¤ºå¼¯éŸ³å™¨ï¼ˆä¸€èˆ¬æ˜¯å¼¯éŸ³è½®æˆ–推æ†ï¼‰äº§ç”Ÿäº†å˜åŒ–。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI system exclusive message. This has behavior exclusive to the device "
"you're receiving input from. Getting this data is not implemented in Godot."
msgstr ""
+"MIDI 系统专有消æ¯ã€‚行为由你所用æ¥èŽ·å–输入的设备专有。Godot 未实现该数æ®çš„获"
+"å–。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI quarter frame message. Contains timing information that is used to "
"synchronize MIDI devices. Getting this data is not implemented in Godot."
msgstr ""
+"MIDI 四分帧消æ¯ã€‚包å«ç”¨äºŽåŒæ­¥ MIDI 设备的时间信æ¯ã€‚Godot 未实现该数æ®çš„获å–。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI song position pointer message. Gives the number of 16th notes since the "
"start of the song. Getting this data is not implemented in Godot."
msgstr ""
+"MIDI 歌曲ä½ç½®æŒ‡é’ˆæ¶ˆæ¯ã€‚æä¾›è‡ªæ­Œæ›²å¼€å§‹ä»¥æ¥æ‰€ç»è¿‡çš„å六分音符数。Godot 未实现该"
+"æ•°æ®çš„获å–。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI song select message. Specifies which sequence or song is to be played. "
"Getting this data is not implemented in Godot."
-msgstr ""
+msgstr "MIDI 歌曲选择消æ¯ã€‚æŒ‡å®šè¦æ’­æ”¾çš„åºåˆ—或歌曲。Godot 未实现该数æ®çš„获å–。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI tune request message. Upon receiving a tune request, all analog "
"synthesizers should tune their oscillators."
-msgstr ""
+msgstr "MIDI 调整请求消æ¯ã€‚收到调整请求åŽï¼Œæ‰€æœ‰æ¨¡æ‹Ÿåˆæˆå™¨éƒ½åº”该调整其晶振。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI timing clock message. Sent 24 times per quarter note when "
"synchronization is required."
-msgstr ""
+msgstr "MIDI 时钟消æ¯ã€‚需è¦åŒæ­¥æ—¶ï¼Œæ¯å››åˆ†éŸ³ç¬¦ä¼šå‘é€ 24 次。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI start message. Start the current sequence playing. This message will be "
"followed with Timing Clocks."
-msgstr ""
+msgstr "MIDI 开始消æ¯ã€‚开始当å‰åºåˆ—的播放。这个消æ¯åŽä¼šè·Ÿéšæ—¶é’Ÿæ¶ˆæ¯ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "MIDI continue message. Continue at the point the sequence was stopped."
-msgstr ""
+msgstr "MIDI 继续消æ¯ã€‚从åºåˆ—åœæ­¢çš„ä½ç½®ç»§ç»­ã€‚"
#: doc/classes/@GlobalScope.xml
msgid "MIDI stop message. Stop the current sequence."
-msgstr ""
+msgstr "MIDI åœæ­¢æ¶ˆæ¯ã€‚åœæ­¢å½“å‰åºåˆ—。"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI active sensing message. This message is intended to be sent repeatedly "
"to tell the receiver that a connection is alive."
-msgstr ""
+msgstr "MIDI 活跃感知消æ¯ã€‚这个消æ¯çš„目的是è¦é‡å¤å‘é€ï¼Œå‘ŠçŸ¥æŽ¥æ”¶æ–¹è¿žæŽ¥ä»å­˜åœ¨ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
"MIDI system reset message. Reset all receivers in the system to power-up "
"status. It should not be sent on power-up itself."
msgstr ""
+"MIDI 系统é‡ç½®æ¶ˆæ¯ã€‚将系统中的所有接收方é‡ç½®ä¸ºä¸Šç”µçжæ€ã€‚本身ä¸åº”在上电时å‘é€ã€‚"
#: doc/classes/@GlobalScope.xml
msgid ""
@@ -4579,13 +4609,12 @@ msgid "Axis-Aligned Bounding Box."
msgstr "轴对é½åŒ…围盒。"
#: doc/classes/AABB.xml
+#, fuzzy
msgid ""
"[AABB] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -4977,10 +5006,10 @@ msgid ""
"[b]Note:[/b] This function only makes sense when the context is started with "
"[constant MODE_CBC_ENCRYPT] or [constant MODE_CBC_DECRYPT]."
msgstr ""
-"èŽ·å–æ­¤ä¸Šä¸‹æ–‡çš„当å‰IV状æ€ï¼ˆè°ƒç”¨[method update]时会更新IV)。通常ä¸éœ€è¦æ­¤å‡½"
-"数。\n"
-"[b]注æ„:[/b]仅当上下文以[constant MODE_CBC_ENCRYPT]或[constant "
-"MODE_CBC_DECRYPT]å¼€å¤´æ—¶ï¼Œæ­¤å‡½æ•°æ‰æœ‰æ„义。"
+"èŽ·å–æ­¤ä¸Šä¸‹æ–‡çš„å½“å‰ IV 状æ€ï¼ˆè°ƒç”¨ [method update] 时会更新 IV)。通常ä¸éœ€è¦æ­¤"
+"函数。\n"
+"[b]注æ„:[/b]仅当上下文以 [constant MODE_CBC_ENCRYPT] 或 [constant "
+"MODE_CBC_DECRYPT] å¼€å¤´æ—¶ï¼Œæ­¤å‡½æ•°æ‰æœ‰æ„义。"
#: doc/classes/AESContext.xml
msgid ""
@@ -7111,8 +7140,8 @@ msgid ""
"animation plays at normal speed. If it's 0.5, then it plays at half speed. "
"If it's 2, then it plays at double speed."
msgstr ""
-"速度缩放比。例如,如果这个值是1,那么动画以正常速度播放。如果是0.5,则以åŠé€Ÿ"
-"播放。如果是2,则以åŒå€é€Ÿåº¦æ’­æ”¾ã€‚"
+"速度缩放比。例如,如果这个值是 1,那么动画以正常速度播放。如果是 0.5,则以åŠ"
+"速播放。如果是 2,则以åŒå€é€Ÿåº¦æ’­æ”¾ã€‚"
#: doc/classes/AnimationPlayer.xml
msgid ""
@@ -10991,7 +11020,7 @@ msgid ""
"Two tap delay and feedback options."
msgstr ""
"为音频总线添加延迟音频效果。在一段时间åŽå›žæ”¾è¾“入信å·ã€‚\n"
-"两个阀值延迟和å馈选项。"
+"两个节æ‹å»¶è¿Ÿå’Œå馈选项。"
#: doc/classes/AudioEffectDelay.xml
msgid ""
@@ -11088,7 +11117,7 @@ msgstr "$DOCS_URL/tutorials/audio/audio_buses.html"
#: doc/classes/AudioEffectDistortion.xml
msgid "Distortion power. Value can range from 0 to 1."
-msgstr "失真度。值的范围å¯åœ¨0到1之间。"
+msgstr "失真度。值的范围å¯åœ¨ 0 到 1 之间。"
#: doc/classes/AudioEffectDistortion.xml
msgid ""
@@ -11550,15 +11579,19 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr "表示[enum FFT_Size]枚举的大å°ã€‚"
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+#, fuzzy
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr "用于录制æ¥è‡ªéº¦å…‹é£Žçš„声音的音频效果。"
#: doc/classes/AudioEffectRecord.xml
+#, fuzzy
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
"å…许用户录制æ¥è‡ªéº¦å…‹é£Žçš„声音。它设置和获å–记录音频文件的格å¼ï¼ˆ8ä½ï¼Œ16使ˆ–压"
"缩)。它检查录音是å¦å¤„于活动状æ€ï¼Œå¦‚果是,则记录声音。然åŽè¿”回记录的样本。"
@@ -14766,7 +14799,6 @@ msgid ""
msgstr "通过相机æºï¼Œæ‚¨å¯ä»¥è®¿é—®è¿žæŽ¥åˆ°è®¾å¤‡çš„å•个物ç†ç›¸æœºã€‚"
#: doc/classes/CameraFeed.xml
-#, fuzzy
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
"device. When enabled, Godot will start capturing frames from the camera "
@@ -14777,9 +14809,9 @@ msgid ""
"background."
msgstr ""
"通过相机æºï¼Œä½ å¯ä»¥è®¿é—®è¿žæŽ¥åˆ°è®¾å¤‡çš„å•个物ç†ç›¸æœºã€‚å¯ç”¨åŽï¼ŒGodot 将开始从相机æ•"
-"获帧,然åŽä½¿ç”¨ã€‚\n"
-"[b]注æ„:[/b]很多相机会返回YCbCr图åƒï¼Œè¿™äº›å›¾åƒè¢«åˆ†æˆä¸¤ä¸ªçº¹ç†ï¼Œéœ€è¦åœ¨ç€è‰²å™¨ä¸­"
-"组åˆã€‚如果你将环境设置为在背景中显示相机图åƒï¼ŒGodot 会自动为将执行此æ“作。"
+"获帧,然åŽä½¿ç”¨ã€‚å¦è¯·å‚阅 [CameraServer]。\n"
+"[b]注æ„:[/b]很多相机会返回 YCbCr 图åƒï¼Œè¿™äº›å›¾åƒè¢«åˆ†æˆä¸¤ä¸ªçº¹ç†ï¼Œéœ€è¦åœ¨ç€è‰²å™¨"
+"中组åˆã€‚如果你将环境设置为在背景中显示相机图åƒï¼ŒGodot 会自动为将执行此æ“作。"
#: doc/classes/CameraFeed.xml
msgid "Returns the unique ID for this feed."
@@ -14836,7 +14868,6 @@ msgid "Server keeping track of different cameras accessible in Godot."
msgstr "æœåŠ¡å™¨è·Ÿè¸ª Godot 中å¯è®¿é—®çš„ä¸åŒæ‘„åƒå¤´ã€‚"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid ""
"The [CameraServer] keeps track of different cameras accessible in Godot. "
"These are external cameras such as webcams or the cameras on your phone.\n"
@@ -14844,42 +14875,39 @@ msgid ""
"[b]Note:[/b] This class is currently only implemented on macOS and iOS. On "
"other platforms, no [CameraFeed]s will be available."
msgstr ""
-"[CameraServer]记录了Godot中å¯è®¿é—®çš„ä¸åŒæ‘„åƒæœºã€‚è¿™äº›æ˜¯å¤–éƒ¨æ‘„åƒæœºï¼Œå¦‚ç½‘ç»œæ‘„åƒæœº"
-"æˆ–æ‰‹æœºä¸Šçš„æ‘„åƒæœºã€‚\n"
-"它主è¦ç”¨äºŽä¸ºARæ¨¡å—æä¾›æ¥è‡ªæ‘„åƒæœºçš„视频资料。"
+"[CameraServer] 记录了 Godot 中å¯è®¿é—®çš„ä¸åŒæ‘„åƒæœºã€‚è¿™äº›æ˜¯å¤–éƒ¨æ‘„åƒæœºï¼Œå¦‚网络摄"
+"åƒå¤´æˆ–æ‰‹æœºä¸Šçš„æ‘„åƒæœºã€‚\n"
+"它主è¦ç”¨äºŽä¸º AR æ¨¡å—æä¾›æ¥è‡ªæ‘„åƒæœºçš„视频æºã€‚\n"
+"[b]注æ„:[/b]这个类目å‰åªåœ¨ macOS å’Œ iOS 上实现。在其他平å°ä¸Šæ²¡æœ‰å¯ç”¨çš„ "
+"[CameraFeed]。"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid "Adds the camera [code]feed[/code] to the camera server."
-msgstr "å°†ç›¸æœºæºæ·»åŠ åˆ°ç›¸æœºæœåŠ¡ã€‚"
+msgstr "å°†ç›¸æœºæº [code]feed[/code] æ·»åŠ åˆ°æ‘„åƒæœºæœåŠ¡å™¨ä¸­ã€‚"
#: doc/classes/CameraServer.xml
msgid "Returns an array of [CameraFeed]s."
msgstr "返回一个 [CameraFeed] 数组。"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid ""
"Returns the [CameraFeed] corresponding to the camera with the given "
"[code]index[/code]."
-msgstr "返回带有给定[code]id[/code]的项的索引。"
+msgstr "返回与给定索引 [code]index[/code] çš„æ‘„åƒæœºå¯¹åº”çš„ [CameraFeed]。"
#: doc/classes/CameraServer.xml
msgid "Returns the number of [CameraFeed]s registered."
msgstr "返回注册的 [CameraFeed] 的数é‡ã€‚"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid "Removes the specified camera [code]feed[/code]."
-msgstr "移除索引[code]idx[/code]处的项目。"
+msgstr "ç§»é™¤æŒ‡å®šçš„ç›¸æœºæº [code]feed[/code]。"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid "Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in)."
msgstr "当添加 [CameraFeed] 时触å‘(例如,æ’入网络摄åƒå¤´ï¼‰ã€‚"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid "Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged)."
msgstr "当移除 [CameraFeed] 时触å‘(例如,拔掉网络摄åƒå¤´ï¼‰ã€‚"
@@ -14888,10 +14916,8 @@ msgid "The RGBA camera image."
msgstr "RGBA 相机图åƒã€‚"
#: doc/classes/CameraServer.xml
-#, fuzzy
msgid "The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image."
-msgstr ""
-"使用 [url=https://en.wikipedia.org/wiki/DEFLATE]DEFLATE[/url] 压缩方法。"
+msgstr "[url=https://zh.wikipedia.org/zh-cn/YCbCr]YCbCr[/url] æ‘„åƒæœºå›¾åƒã€‚"
#: doc/classes/CameraServer.xml
msgid "The Y component camera image."
@@ -14996,13 +15022,13 @@ msgid ""
msgstr "引擎调用的å¯è¦†ç›–函数(如果定义了)æ¥ç»˜åˆ¶ç”»å¸ƒé¡¹ç›®ã€‚"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws a unfilled arc between the given angles. The larger the value of "
"[code]point_count[/code], the smoother the curve. See also [method "
"draw_circle]."
msgstr ""
-"在给定的角度之间画一æ¡å¼§çº¿ã€‚[code]point_count[/code] 的值越大,曲线越平滑。"
+"在给定的角度之间绘制未填充的弧线。[code]point_count[/code] 的值越大,曲线越平"
+"滑。å¦è¯·å‚阅 [method draw_circle]。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15017,33 +15043,35 @@ msgid ""
"Draws a colored, unfilled circle. See also [method draw_arc], [method "
"draw_polyline] and [method draw_polygon]."
msgstr ""
+"ç»˜åˆ¶ä¸€ä¸ªå½©è‰²ã€æœªå¡«å……的圆。å¦è¯·å‚阅 [method draw_arc]ã€[method "
+"draw_polyline]ã€[method draw_polygon]。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws a colored polygon of any amount of points, convex or concave. Unlike "
"[method draw_polygon], a single color must be specified for the whole "
"polygon."
-msgstr "ç»˜åˆ¶ä»»æ„æ•°é‡ç‚¹çš„彩色多边形,凸或凹。"
+msgstr ""
+"ç»˜åˆ¶ç”±ä»»æ„æ•°é‡çš„点构æˆçš„彩色多边形,å¯ä»¥æ˜¯å‡¸å¤šè¾¹å½¢ä¹Ÿå¯ä»¥æ˜¯å‡¹å¤šè¾¹å½¢ã€‚与 "
+"[method draw_polygon] ä¸åŒï¼Œåªèƒ½ä¸ºæ•´ä¸ªå¤šè¾¹å½¢å¿…须指定å•一颜色。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws a line from a 2D point to another, with a given color and width. It "
"can be optionally antialiased. See also [method draw_multiline] and [method "
"draw_polyline]."
msgstr ""
-"绘制一æ¡ä»Ž 2D 点到å¦ä¸€ä¸ªç‚¹çš„线,具有给定的颜色和宽度。它å¯ä»¥é€‰æ‹©æŠ—锯齿。"
+"使用给定的颜色和宽度,绘制一æ¡ä»Žä¸€ä¸ª 2D 点到å¦ä¸€ä¸ªç‚¹çš„直线。还å¯ä»¥é€‰æ‹©æŠ—锯"
+"齿。å¦è¯·å‚阅 [method draw_multiline] å’Œ [method draw_polyline]。"
#: doc/classes/CanvasItem.xml
msgid ""
"Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for "
"related documentation."
msgstr ""
-"使用所æä¾›çš„纹ç†ä»¥2Dæ–¹å¼ç»˜åˆ¶ä¸€ä¸ª[Mesh]。相关文档请å‚阅[MeshInstance2D]。"
+"使用所æä¾›çš„纹ç†ä»¥ 2D æ–¹å¼ç»˜åˆ¶ä¸€ä¸ª [Mesh]。相关文档请å‚阅 [MeshInstance2D]。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws multiple disconnected lines with a uniform [code]color[/code]. When "
"drawing large amounts of lines, this is faster than using individual [method "
@@ -15052,13 +15080,13 @@ msgid ""
"[b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are currently "
"not implemented and have no effect."
msgstr ""
-"以 uniform çš„ [code]width[/code] å’Œé€æ®µç€è‰²ç»˜åˆ¶å¤šæ¡å¹³è¡Œçº¿ã€‚分é…给线段的颜色"
-"按 [code]points[/code] å’Œ [code]colors[/code] 之间的索引匹é…。\n"
-"[b]注æ„:[/b][code]width[/code] å’Œ [code]antialiased[/code] ç›®å‰æ²¡æœ‰å®žçŽ°ï¼Œæ²¡"
-"有效果。"
+"使用å•一颜色 [code]color[/code] 绘制多æ¡ä¸ç›¸è¿žçš„直线。绘制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独"
+"调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ç›¸è¿žçš„直线,请æ¢ç”¨ [method "
+"draw_polyline]。\n"
+"[b]注æ„:[/b]ç›®å‰æœªå®žçް [code]width[/code] å’Œ [code]antialiased[/code],没有"
+"效果。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws multiple disconnected lines with a uniform [code]width[/code] and "
"segment-by-segment coloring. Colors assigned to line segments match by index "
@@ -15069,10 +15097,12 @@ msgid ""
"[b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are currently "
"not implemented and have no effect."
msgstr ""
-"以 uniform çš„ [code]width[/code] å’Œé€æ®µç€è‰²ç»˜åˆ¶å¤šæ¡å¹³è¡Œçº¿ã€‚分é…给线段的颜色"
-"按 [code]points[/code] å’Œ [code]colors[/code] 之间的索引匹é…。\n"
-"[b]注æ„:[/b][code]width[/code] å’Œ [code]antialiased[/code] ç›®å‰æ²¡æœ‰å®žçŽ°ï¼Œæ²¡"
-"有效果。"
+"使用å•一宽度 [code]width[/code] 绘制多æ¡ä¸ç›¸è¿žçš„直线,ä¸åŒçº¿æ®µé¢œè‰²å¯ä»¥ä¸åŒã€‚"
+"线段的颜色使用 [code]points[/code] å’Œ [code]colors[/code] 的索引进行匹é…。绘"
+"制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ç›¸è¿žçš„直线,请æ¢ç”¨ "
+"[method draw_polyline_colors]。\n"
+"[b]注æ„:[/b]ç›®å‰æœªå®žçް [code]width[/code] å’Œ [code]antialiased[/code],没有"
+"效果。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15089,6 +15119,9 @@ msgid ""
"individually. See also [method draw_polyline] and [method "
"draw_polyline_colors]."
msgstr ""
+"ç»˜åˆ¶ç”±ä»»æ„æ•°é‡çš„点构æˆçš„实心多边形,å¯ä»¥æ˜¯å‡¸å¤šè¾¹å½¢ä¹Ÿå¯ä»¥æ˜¯å‡¹å¤šè¾¹å½¢ã€‚与 "
+"[method draw_colored_polygon] ä¸åŒï¼Œæ¯ä¸ªç‚¹çš„颜色都å¯ä»¥å•独修改。å¦è¯·å‚阅 "
+"[method draw_polyline] 和 [method draw_polyline_colors]。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15098,9 +15131,12 @@ msgid ""
"draw disconnected lines, use [method draw_multiline] instead. See also "
"[method draw_polygon]."
msgstr ""
+"使用å•一颜色 [code]color[/code] 和宽度 [code]width[/code] 绘制多æ¡ç›¸è¿žçš„线"
+"段,还å¯ä»¥é€‰æ‹©æŠ—锯齿。绘制大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦"
+"绘制ä¸ç›¸è¿žçš„直线,请æ¢ç”¨ [method draw_multiline]。å¦è¯·å‚阅 [method "
+"draw_polygon]。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Draws interconnected line segments with a uniform [code]width[/code] and "
"segment-by-segment coloring, and optional antialiasing. Colors assigned to "
@@ -15109,8 +15145,10 @@ msgid ""
"individual [method draw_line] calls. To draw disconnected lines, use [method "
"draw_multiline_colors] instead. See also [method draw_polygon]."
msgstr ""
-"以uniformçš„[code]width[/code]ç»˜åˆ¶ç›¸äº’è¿žæŽ¥çš„çº¿æ®µï¼Œé€æ®µç€è‰²ï¼Œå¯é€‰æŠ—锯齿。分é…ç»™"
-"线段的颜色通过[code]points[/code]å’Œ[code]colors[/code]之间的索引进行匹é…。"
+"使用å•一宽度 [code]width[/code] 绘制多æ¡ç›¸è¿žçš„直线,ä¸åŒçº¿æ®µé¢œè‰²å¯ä»¥ä¸åŒã€‚线"
+"段的颜色使用 [code]points[/code] å’Œ [code]colors[/code] 的索引进行匹é…。绘制"
+"大é‡ç›´çº¿æ—¶ï¼Œæ¯”å•独调用 [method draw_line] è¦å¿«ã€‚è¦ç»˜åˆ¶ä¸ç›¸è¿žçš„直线,请æ¢ç”¨ "
+"[method draw_multiline_colors]。å¦è¯·å‚阅 [method draw_polygon]。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15120,6 +15158,10 @@ msgid ""
"See also [method draw_line], [method draw_polyline], [method draw_polygon], "
"and [method draw_rect]."
msgstr ""
+"绘制自定义图元。1 个点的是个点,2 个点的是线段,3 个点的是三角形,4 个点的是"
+"四边形。如果没有指定点或者指定了超过 4 个点,则ä¸ä¼šç»˜åˆ¶ä»»ä½•东西,åªä¼šè¾“出错误"
+"消æ¯ã€‚å¦è¯·å‚阅 [method draw_line]ã€[method draw_polyline]ã€[method "
+"draw_polygon]ã€[method draw_rect]。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15262,11 +15304,12 @@ msgid "Returns the [World2D] where this item is in."
msgstr "è¿”å›žæ­¤ç‰©å“æ‰€åœ¨çš„[World2D]。"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Hide the [CanvasItem] if it's currently visible. This is equivalent to "
"setting [member visible] to [code]false[/code]."
-msgstr "清空数组。与调用 [method resize] 时指定大å°ä¸º [code]0[/code] 等价。"
+msgstr ""
+"如果该 [CanvasItem] ç›®å‰æ˜¯å¯è§çš„,则将其éšè—。等价于将 [member visible] 设为 "
+"[code]false[/code]。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15331,15 +15374,15 @@ msgstr ""
"如果[code]enable[/code]为[code]true[/code]ï¼Œåˆ™å°†ä½¿ç”¨å…¨å±€å˜æ¢æ•°æ®æ›´æ–°å­é¡¹ã€‚"
#: doc/classes/CanvasItem.xml
-#, fuzzy
msgid ""
"Show the [CanvasItem] if it's currently hidden. This is equivalent to "
"setting [member visible] to [code]true[/code]. For controls that inherit "
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-"如果[CanvasItem]当剿˜¯éšè—的,则显示它。对于继承[Popup]的控件,使其å¯è§çš„æ­£ç¡®"
-"方法是调用多个[code]popup*()[/code]函数中的一个æ¥ä»£æ›¿ã€‚"
+"如果该 [CanvasItem] ç›®å‰æ˜¯éšè—的,则将其显示。等价于将 [member visible] 设为 "
+"[code]true[/code]。对于继承自 [Popup] 的控件,让它们å¯è§çš„æ­£ç¡®åšæ³•æ˜¯æ¢æˆè°ƒç”¨"
+"å„ç§ [code]popup*()[/code] 函数的其中之一。"
#: doc/classes/CanvasItem.xml
msgid ""
@@ -15581,8 +15624,8 @@ msgid ""
"above), or backgrounds (in layer -1 or below)."
msgstr ""
"画布绘图层。[CanvasLayer] 的直接或间接å­çº§çš„ [CanvasItem] 节点将在该层中绘"
-"制。该层是一个数字索引,用于定义绘制顺åºã€‚默认 2D 场景的渲染索引为 0,因此索"
-"引为 -1 的 [CanvasLayer] 会在其下方绘制,索引为 1 的则会在其上方绘制。这对于 "
+"制。层是一个决定绘制顺åºçš„æ•°å­—索引。默认 2D 场景的渲染索引为 0,因此索引为 "
+"-1 的 [CanvasLayer] 会在其下方绘制,索引为 1 的则会在其上方绘制。这对于 "
"HUD(在 1+ 层或更高层中)或背景(在 -1 层或更低层中)éžå¸¸æœ‰ç”¨ã€‚"
#: doc/classes/CanvasLayer.xml
@@ -15703,13 +15746,15 @@ msgstr "使å­çº§æŽ§ä»¶å±…中。"
msgid ""
"CenterContainer keeps children controls centered. This container keeps all "
"children to their minimum size, in the center."
-msgstr "CenterContainer使å­èŠ‚ç‚¹å±…ä¸­ã€‚è¯¥å®¹å™¨å°†æ‰€æœ‰å­èŠ‚ç‚¹ä¿æŒåœ¨æœ€å°å°ºå¯¸çš„中间。"
+msgstr ""
+"CenterContainer 会使å­èŠ‚ç‚¹å±…ä¸­ã€‚è¯¥å®¹å™¨ä¼šå°†æ‰€æœ‰å­èŠ‚ç‚¹ä¿æŒåœ¨æœ€å°å°ºå¯¸å¹¶å±…中。"
#: doc/classes/CenterContainer.xml
msgid ""
"If [code]true[/code], centers children relative to the [CenterContainer]'s "
"top left corner."
-msgstr "如果[code]true[/code],将å­èŠ‚ç‚¹ç›¸å¯¹äºŽ[CenterContainer]的左上角居中。"
+msgstr ""
+"如果为 [code]true[/code],会将å­èŠ‚ç‚¹ç›¸å¯¹äºŽ [CenterContainer] 的左上角居中。"
#: doc/classes/CharFXTransform.xml
msgid ""
@@ -15735,11 +15780,12 @@ msgstr ""
"https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project"
#: doc/classes/CharFXTransform.xml
-#, fuzzy
msgid ""
"The index of the current character (starting from 0) for the "
"[RichTextLabel]'s BBCode text. Setting this property won't affect drawing."
-msgstr "当å‰å­—符的索引(从0开始)。设置此属性ä¸ä¼šå½±å“图形。"
+msgstr ""
+"该 [RichTextLabel] çš„ BBCode 文本中当å‰å­—符的索引å·ï¼ˆä»Ž 0 开始)。设置该属性"
+"ä¸ä¼šå½±å“绘制。"
#: doc/classes/CharFXTransform.xml
msgid ""
@@ -15807,11 +15853,12 @@ msgid "The position offset the character will be drawn with (in pixels)."
msgstr "绘制字符的ä½ç½®åç§»é‡ï¼ˆä»¥åƒç´ ä¸ºå•ä½ï¼‰ã€‚"
#: doc/classes/CharFXTransform.xml
-#, fuzzy
msgid ""
"The index of the current character (starting from 0) for this "
"[RichTextEffect] custom block. Setting this property won't affect drawing."
-msgstr "当å‰å­—符的索引(从0开始)。设置此属性ä¸ä¼šå½±å“图形。"
+msgstr ""
+"该 [RichTextEffect] 自定义å—中当å‰å­—符的索引å·ï¼ˆä»Ž 0 开始)。设置该属性ä¸ä¼šå½±"
+"å“绘制。"
#: doc/classes/CharFXTransform.xml
msgid ""
@@ -16527,7 +16574,7 @@ msgid ""
msgstr ""
"当对象收到未处ç†çš„ [InputEvent] æ—¶å‘出。 [code]position[/code] 是鼠标指针在具"
"有索引 [code]shape_idx[/code] 的形状表é¢åœ¨ä¸–界空间中的ä½ç½®ï¼Œ[code]normal[/"
-"code] 是该点表é¢çš„æ³•å‘é‡."
+"code] 是该点表é¢çš„æ³•å‘é‡ã€‚"
#: doc/classes/CollisionObject.xml
msgid "Emitted when the mouse pointer enters any of this object's shapes."
@@ -16890,7 +16937,6 @@ msgid "Color in RGBA format using floats on the range of 0 to 1."
msgstr "RGBA æ ¼å¼çš„颜色,使用 0 到 1 范围内的浮点数。"
#: doc/classes/Color.xml
-#, fuzzy
msgid ""
"A color represented by red, green, blue, and alpha (RGBA) components. The "
"alpha component is often used for opacity. Values are in floating-point and "
@@ -16908,9 +16954,9 @@ msgid ""
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
"color_constants.png]Color constants cheatsheet[/url]"
msgstr ""
-"由红ã€ç»¿ã€è“ã€Alpha(RGBA)分é‡è¡¨ç¤ºçš„颜色。Alpha 分é‡é€šå¸¸ç”¨äºŽé€æ˜Žåº¦ã€‚这些值都"
-"是浮点数,范围一般在 0 到 1 之间。有些属性(如 CanvasItem.modulate)å¯ä»¥æŽ¥å—"
-"大于 1 的值(过亮或 HDR 颜色)。\n"
+"由红ã€ç»¿ã€è“ã€Alpha(RGBA)分é‡è¡¨ç¤ºçš„颜色。Alpha 分é‡é€šå¸¸ç”¨äºŽä¸é€æ˜Žåº¦ã€‚这些值"
+"都是浮点数,范围一般在 0 到 1 之间。有些属性(如 CanvasItem.modulate)å¯ä»¥æŽ¥"
+"å—大于 1 的值(过亮或 HDR 颜色)。\n"
"您也å¯ä»¥é€šè¿‡ä½¿ç”¨ [method @GDScript.ColorN] 从标准化颜色å称中创建颜色,或者直"
"接使用这里定义的颜色常é‡ã€‚标准化颜色集å–自 [url=https://en.wikipedia.org/"
"wiki/X11_color_names]X11 颜色åç§°[/url]。\n"
@@ -17268,6 +17314,8 @@ msgid ""
"means that the color is fully transparent. A value of 1 means that the color "
"is fully opaque."
msgstr ""
+"颜色的 Alpha 分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。0 è¡¨ç¤ºè¯¥é¢œè‰²å®Œå…¨é€æ˜Žã€‚1 表示该颜色"
+"完全ä¸é€æ˜Žã€‚"
#: doc/classes/Color.xml
msgid "Wrapper for [member a] that uses the range 0 to 255 instead of 0 to 1."
@@ -17275,7 +17323,7 @@ msgstr "[member a]的包装程åºï¼Œä½¿ç”¨çš„范围是0到255ï¼Œè€Œä¸æ˜¯0到1ã€
#: doc/classes/Color.xml
msgid "The color's blue component, typically on the range of 0 to 1."
-msgstr "颜色的è“色分é‡ï¼Œä¸€èˆ¬åœ¨0到1的范围内。"
+msgstr "颜色的è“色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。"
#: doc/classes/Color.xml
msgid "Wrapper for [member b] that uses the range 0 to 255 instead of 0 to 1."
@@ -17283,7 +17331,7 @@ msgstr "[member b]çš„å°è£…器,使用0到255çš„èŒƒå›´ï¼Œè€Œä¸æ˜¯0到1。"
#: doc/classes/Color.xml
msgid "The color's green component, typically on the range of 0 to 1."
-msgstr "颜色的绿色分é‡ï¼Œä¸€èˆ¬åœ¨0到1的范围内。"
+msgstr "颜色的绿色分é‡ï¼Œä¸€èˆ¬åœ¨ 0 到 1 的范围内。"
#: doc/classes/Color.xml
msgid "Wrapper for [member g] that uses the range 0 to 255 instead of 0 to 1."
@@ -17941,9 +17989,8 @@ msgstr ""
"动事件中也会立å³åº”用(ä¼šé€ æˆæ€§èƒ½é—®é¢˜)。"
#: doc/classes/ColorPicker.xml
-#, fuzzy
msgid "If [code]true[/code], shows an alpha channel slider (opacity)."
-msgstr "如果 [code]true[/code],显示 Alpha é€šé“æ»‘å—ï¼ˆé€æ˜Žåº¦ï¼‰ã€‚"
+msgstr "如果为 [code]true[/code],则显示 Alpha é€šé“æ»‘动æ¡ï¼ˆä¸é€æ˜Žåº¦ï¼‰ã€‚"
#: doc/classes/ColorPicker.xml
msgid ""
@@ -18843,12 +18890,12 @@ msgstr ""
"[method Node._unhandled_input]或[method Node._unhandled_key_input]的节点。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -18872,23 +18919,25 @@ msgstr ""
"[/codeblock]"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
-"为指定 [code]name[/code] 的主题常é‡åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°è¦†"
-"盖项始终优先。无法删除覆盖项,但å¯ä»¥ä½¿ç”¨ç›¸åº”的默认值覆盖它。\n"
-"å‚阅[method get_constant]。"
+"为指定 [code]name[/code] 的主题ç€è‰²å™¨åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°"
+"覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ é™¤è¦†ç›–。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
"使用指定的 [code]name[/code] 为主题 [Font] åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹"
@@ -18896,11 +18945,14 @@ msgstr ""
"å‚阅[method get_font]。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
"为指定 [code]name[/code] çš„ä¸»é¢˜å›¾æ ‡åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°è¦†"
@@ -18908,21 +18960,28 @@ msgstr ""
"å‚阅[method get_icon]。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
-"为指定 [code]name[/code] 的主题ç€è‰²å™¨åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹æ—¶ï¼Œæœ¬åœ°"
-"覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ é™¤è¦†ç›–。"
+"使用指定的 [code]name[/code] 为主题 [Font] åˆ›å»ºæœ¬åœ°è¦†ç›–é¡¹ã€‚èŽ·å–æŽ§ä»¶çš„ä¸»é¢˜é¡¹"
+"时,本地覆盖项始终优先。å¯ä»¥é€šè¿‡ä¸ºå…¶åˆ†é… [code]null[/code] 值æ¥åˆ é™¤è¦†ç›–。\n"
+"å‚阅[method get_font]。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -19430,6 +19489,39 @@ msgid ""
msgstr "放弃焦点。其他控件将无法接收键盘输入。"
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "移除按键[code]name[/code]的动画。"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "移除按键[code]name[/code]的动画。"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "移除按键[code]name[/code]的动画。"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "移除按键[code]name[/code]的动画。"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "返回带有给定[code]id[/code]的项的索引。"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "返回带有给定[code]id[/code]的项的索引。"
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -19980,9 +20072,9 @@ msgid ""
"[member rect_scale], it will scale around this pivot. Set this property to "
"[member rect_size] / 2 to center the pivot in the node's rectangle."
msgstr ""
-"默认情况下,节点的轴是其左上角。当您更改其[member rect_scale]时,它将围绕此枢"
-"轴进行缩放。将此属性设置为[member rect_size] / 2,以将枢轴在节点的矩形中居"
-"中。"
+"默认情况下,该节点的轴心ä½äºŽå…¶å·¦ä¸Šè§’。当您更改其 [member rect_scale] 时,它将"
+"围绕此轴心进行缩放。将此属性设置为 [member rect_size] / 2,以将轴心在节点的矩"
+"形中居中。"
#: doc/classes/Control.xml
msgid ""
@@ -19990,16 +20082,16 @@ msgid ""
"rectangle's top-left corner. The property is not affected by [member "
"rect_pivot_offset]."
msgstr ""
-"节点相对于其父节点的ä½ç½®ã€‚它对应于矩形的左上角。该属性ä¸å—[member "
-"rect_pivot_offset]的影å“。"
+"节点相对于其父节点的ä½ç½®ã€‚它对应于矩形的左上角。该属性ä¸å— [member "
+"rect_pivot_offset] 的影å“。"
#: doc/classes/Control.xml
msgid ""
"The node's rotation around its pivot, in degrees. See [member "
"rect_pivot_offset] to change the pivot's position."
msgstr ""
-"节点围绕其枢轴的旋转(以度为å•ä½ï¼‰ã€‚请å‚阅[member rect_pivot_offset]更改枢轴"
-"çš„ä½ç½®ã€‚"
+"节点围绕其轴心的旋转(以度为å•ä½ï¼‰ã€‚更改轴心的ä½ç½®è¯·å‚阅 [member "
+"rect_pivot_offset]。"
#: doc/classes/Control.xml
msgid ""
@@ -20108,12 +20200,21 @@ msgstr ""
"mouse_entered]。"
#: doc/classes/Control.xml
+#, fuzzy
msgid ""
"Emitted when the mouse leaves the control's [code]Rect[/code] area, provided "
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
"当鼠标离开控件的[code]Rect[/code]区域时触å‘,åªè¦å…¶[member mouse_filter]å…许"
"事件到达。\n"
@@ -20672,6 +20773,8 @@ msgid ""
"[method set_point_cloud] to generate a convex hull shape from concave shape "
"points."
msgstr ""
+"è¯¥å¤šè¾¹å½¢çš„é¡¶ç‚¹åˆ—è¡¨ã€‚é¡ºæ—¶é’ˆé¡ºåºæˆ–逆时针顺åºéƒ½æœ‰å¯èƒ½ã€‚请用凸包点设置该属性,å¯"
+"以用 [method set_point_cloud] 从凹形状点设æˆå‡¸åŒ…形状。"
#: doc/classes/CPUParticles.xml
msgid "CPU-based 3D particle emitter."
@@ -22226,9 +22329,8 @@ msgstr ""
"å¦è¯·å‚阅[GodotSharp]。"
#: modules/mono/doc_classes/CSharpScript.xml
-#, fuzzy
msgid "$DOCS_URL/tutorials/scripting/c_sharp/index.html"
-msgstr "$DOCS_URL/tutorials/scripting/index.html"
+msgstr "$DOCS_URL/tutorials/scripting/c_sharp/index.html"
#: modules/mono/doc_classes/CSharpScript.xml
#: modules/gdnative/doc_classes/PluginScript.xml
@@ -24245,6 +24347,8 @@ msgid ""
"font oversampling, ignoring [member SceneTree.use_font_oversampling] value "
"and viewport stretch mode."
msgstr ""
+"如果设为比 [code]0.0[/code] 大的值,则会覆盖默认的字体过采样,忽略 [member "
+"SceneTree.use_font_oversampling] çš„å€¼å’Œè§†å£æ‹‰ä¼¸æ¨¡å¼ã€‚"
#: doc/classes/DynamicFontData.xml
msgid "Disables font hinting (smoother but less crisp)."
@@ -24263,7 +24367,6 @@ msgid "A script that is executed when exporting the project."
msgstr "在导出项目时执行的脚本。"
#: doc/classes/EditorExportPlugin.xml
-#, fuzzy
msgid ""
"[EditorExportPlugin]s are automatically invoked whenever the user exports "
"the project. Their most common use is to determine what files are being "
@@ -24273,9 +24376,11 @@ msgid ""
"To use [EditorExportPlugin], register it using the [method EditorPlugin."
"add_export_plugin] method first."
msgstr ""
-"æ¯å½“用户导出项目时,会自动激活编辑器的导出æ’件。其最常用在确定哪些文件被包å«"
-"到导出的项目中。对于æ¯ä¸ªæ’件,在导出过程开始时调用[method _export_begin],然"
-"åŽè°ƒç”¨æ¯ä¸ªå¯¼å‡ºæ–‡ä»¶çš„[method _export_file]。"
+"[EditorExportPlugin] 会在用户导出项目时自动调用。它们最常è§çš„用途是确定哪些文"
+"件应该包å«åœ¨å¯¼å‡ºçš„项目中。对于æ¯ä¸ªæ’件,导出过程开始时都会调用 [method "
+"_export_begin],然åŽä¼šä¸ºæ¯ä¸€ä¸ªå¯¼å‡ºçš„æ–‡ä»¶è°ƒç”¨ [method _export_file]。\n"
+"è¦ä½¿ç”¨ [EditorExportPlugin],请先用 [method EditorPlugin.add_export_plugin] "
+"注册。"
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -24369,7 +24474,7 @@ msgstr "为iOS属性列表文件添加内容。"
#: doc/classes/EditorExportPlugin.xml
msgid "Adds a static lib from the given [code]path[/code] to the iOS project."
-msgstr "从给定的[code]path[/code]æ·»åŠ é™æ€åº“到iOS项目。"
+msgstr "å°†ä½äºŽç»™å®šè·¯å¾„ [code]path[/code] çš„é™æ€åº“添加到 iOS 项目中。"
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -24377,6 +24482,9 @@ msgid ""
"directory of macOS app bundle.\n"
"[b]Note:[/b] This is useful only for macOS exports."
msgstr ""
+"将与路径 [code]path[/code] 相匹é…的文件或目录添加到 macOS App æ†ç»‘包的 "
+"[code]PlugIns[/code] 目录中。\n"
+"[b]注æ„:[/b]仅适用于 macOS 导出。"
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -24387,6 +24495,11 @@ msgid ""
"In case of a directory code-sign will error if you place non code object in "
"directory."
msgstr ""
+"添加共享对象或仅包å«å…±äº«å¯¹è±¡çš„目录,共享对象ä½äºŽ [code]path[/code],需è¦ä¸Žç»™"
+"定的 [code]tags[/code] 标签匹é…。\n"
+"[b]注æ„:[/b]使用 macOS 导出时,这些共享对象会被加入到 App æ†ç»‘包的 "
+"[code]Frameworkds[/code] 目录。\n"
+"如果使用的是目录,并且你在该目录中加入了éžä»£ç å¯¹è±¡ï¼Œåˆ™ä»£ç ç­¾å时会报错。"
#: doc/classes/EditorExportPlugin.xml
msgid ""
@@ -24897,7 +25010,6 @@ msgstr ""
"æºç±»åž‹å¯¼å…¥ã€‚"
#: doc/classes/EditorImportPlugin.xml
-#, fuzzy
msgid ""
"[EditorImportPlugin]s provide a way to extend the editor's resource import "
"functionality. Use them to import resources from custom files or to provide "
@@ -24954,16 +25066,15 @@ msgid ""
"To use [EditorImportPlugin], register it using the [method EditorPlugin."
"add_import_plugin] method first."
msgstr ""
-"EditorImportPluginsæä¾›äº†ä¸€ç§æ‰©å±•编辑器资æºå¯¼å…¥åŠŸèƒ½çš„æ–¹æ³•ã€‚ä½¿ç”¨å®ƒä»¬æ¥å¯¼å…¥è‡ªå®š"
-"义文件中的资æºï¼Œæˆ–æˆä¸ºç¼–辑器现有导入器的替代å“。用[method EditorPlugin."
-"add_import_plugin]注册你的[EditorPlugin]。\n"
-"EditorImportPlugins通过与特定的文件扩展å和资æºç±»åž‹ç›¸å…³è”æ¥å·¥ä½œã€‚å‚阅 "
+"[EditorImportPlugin] æä¾›äº†ä¸€ç§æ‰©å±•编辑器资æºå¯¼å…¥åŠŸèƒ½çš„æ–¹æ³•ã€‚ä½¿ç”¨å®ƒä»¬æ¥å¯¼å…¥è‡ª"
+"定义文件中的资æºï¼Œæˆ–æˆä¸ºç¼–辑器现有导入器的替代å“。\n"
+"EditorImportPlugin 通过与特定的文件扩展å和资æºç±»åž‹ç›¸å…³è”æ¥å·¥ä½œã€‚å‚阅 "
"[method get_recognized_extensions] å’Œ [method get_resource_type]。其å¯ä»¥é€‰æ‹©"
-"性地指定一些影å“导入过程的导入预置。EditorImportPlugins负责创建资æºå¹¶å°†å…¶ä¿å­˜"
-"在[code].import[/code]目录中,å‚阅[member ProjectSettings.application/config/"
-"use_hidden_project_data_directory]。\n"
-"䏋颿˜¯ä¸€ä¸ªEditorImportPlugin的例å­ï¼Œå®ƒä»Žæ‰©å±•å为 \".special\" 或 \".spec\" çš„"
-"文件中导入一个[Mesh]:\n"
+"性地指定一些影å“导入过程的导入预置。EditorImportPlugin 负责创建资æºå¹¶å°†å…¶ä¿å­˜"
+"在 [code].import[/code] 目录中,å‚阅 [member ProjectSettings.application/"
+"config/use_hidden_project_data_directory]。\n"
+"䏋颿˜¯ä¸€ä¸ª EditorImportPlugin 的例å­ï¼Œå®ƒä¼šä»Žæ‰©å±•å为“.specialâ€æˆ–“.specâ€çš„æ–‡ä»¶"
+"中导入一个 [Mesh]:\n"
"[codeblock]\n"
"tool\n"
"extends EditorImportPlugin\n"
@@ -24998,12 +25109,13 @@ msgstr ""
" return FAILED\n"
"\n"
" var mesh = Mesh.new()\n"
-" # Fill the Mesh with data read in \"file\", left as an exercise to the "
-"reader\n"
+" # 使用从“fileâ€ä¸­è¯»å–的数æ®å¡«å…… Mesh,留作读者的练习\n"
"\n"
" var filename = save_path + \".\" + get_save_extension()\n"
" return ResourceSaver.save(filename, mesh)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"è¦ä½¿ç”¨ä½ çš„ [EditorImportPlugin],请先通过 [method EditorPlugin."
+"add_import_plugin] 注册。"
#: doc/classes/EditorImportPlugin.xml doc/classes/ResourceImporter.xml
msgid "$DOCS_URL/tutorials/plugins/editor/import_plugins.html"
@@ -25221,7 +25333,6 @@ msgid "Plugin for adding custom property editors on inspector."
msgstr "用于在检查器上添加自定义属性编辑器的æ’件。"
#: doc/classes/EditorInspectorPlugin.xml
-#, fuzzy
msgid ""
"[EditorInspectorPlugin] allows adding custom property editors to "
"[EditorInspector].\n"
@@ -25237,15 +25348,17 @@ msgid ""
"To use [EditorInspectorPlugin], register it using the [method EditorPlugin."
"add_inspector_plugin] method first."
msgstr ""
-"该æ’ä»¶å…许å‘[EditorInspector]添加自定义属性编辑器。\n"
-"æ’件通过[method EditorPlugin.add_inspector_plugin]注册。\n"
-"当一个对象被编辑时,[method can_handle]函数被调用,如果支æŒå¯¹è±¡ç±»åž‹ï¼Œå¿…须返回"
-"[code]true[/code]。\n"
-"如果支æŒï¼Œå‡½æ•°[method parse_begin]将被调用,å…许在类的开头放置自定义控件。\n"
-"éšåŽï¼Œè°ƒç”¨æ¯ä¸ªç±»åž‹å’Œå±žæ€§[method parse_category]å’Œ[method parse_property]。其"
-"也æä¾›äº†å‘检查器添加自定义控件的能力。\n"
-"最åŽï¼Œè°ƒç”¨[method parse_end]。\n"
-"在这些调用中,æ¯ä¸€ä¸ªéƒ½å¯ä»¥è°ƒç”¨ \"add\"函数。"
+"[EditorInspectorPlugin] å¯ç”¨äºŽå‘ [EditorInspector] 添加自定义属性编辑器。\n"
+"当一个对象被编辑时,[method can_handle] 函数被调用,如果支æŒå¯¹è±¡ç±»åž‹ï¼Œå¿…须返"
+"回 [code]true[/code]。\n"
+"如果支æŒï¼Œå‡½æ•° [method parse_begin] 将被调用,å…许在类的开头放置自定义控"
+"件。\n"
+"éšåŽï¼Œè°ƒç”¨æ¯ä¸ªç±»åž‹å’Œå±žæ€§ [method parse_category] å’Œ [method parse_property]。"
+"其也æä¾›äº†å‘检查器添加自定义控件的能力。\n"
+"最åŽï¼Œè°ƒç”¨ [method parse_end]。\n"
+"在这些调用中,æ¯ä¸€ä¸ªéƒ½å¯ä»¥è°ƒç”¨â€œaddâ€å‡½æ•°ã€‚\n"
+"è¦ä½¿ç”¨ [EditorInspectorPlugin],请先通过 [method EditorPlugin."
+"add_inspector_plugin] 方法注册。"
#: doc/classes/EditorInspectorPlugin.xml
msgid "$DOCS_URL/tutorials/plugins/editor/inspector_plugins.html"
@@ -25520,7 +25633,7 @@ msgstr "将场景ä¿å­˜ä¸º[code]path[/code]处的文件。"
msgid ""
"Selects the file, with the path provided by [code]file[/code], in the "
"FileSystem dock."
-msgstr "选择文件,路径由[code]file[/code]æä¾›ï¼Œåœ¨æ–‡ä»¶ç³»ç»Ÿé¢æ¿å¤„。"
+msgstr "åœ¨æ–‡ä»¶ç³»ç»Ÿé¢æ¿ä¸­é€‰ä¸­æ–‡ä»¶ï¼Œè·¯å¾„ç”± [code]file[/code] æä¾›ã€‚"
#: doc/classes/EditorInterface.xml
msgid ""
@@ -25553,7 +25666,7 @@ msgstr ""
#: doc/classes/EditorPlugin.xml
msgid "Used by the editor to extend its functionality."
-msgstr "由编辑器用于扩展其功能。"
+msgstr "由编辑器使用,用于扩展其功能。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -25599,12 +25712,11 @@ msgid ""
"with [method remove_control_from_container] and free it with [method Node."
"queue_free]."
msgstr ""
-"将自定义控件添加到容器中(å‚阅[enum CustomControlContainer])。在编辑器用户界"
-"é¢ä¸­ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ï¼Œè¯·è®°ä½ï¼Œæ‚¨å¿…é¡»è‡ªå·±ç®¡ç†æ‚¨çš„自定义控件的å¯"
-"è§æ€§ï¼ˆå¹¶ä¸”很å¯èƒ½åœ¨æ·»åŠ åŽéšè—它)。\n"
+"将自定义控件添加到容器中(å‚阅 [enum CustomControlContainer])。在编辑器用户"
+"界é¢ä¸­ï¼Œæœ‰è®¸å¤šä½ç½®å¯ä»¥æ·»åŠ è‡ªå®šä¹‰æŽ§ä»¶ã€‚\n"
"请记ä½ï¼Œæ‚¨å¿…é¡»è‡ªå·±ç®¡ç†æ‚¨çš„自定义控件的å¯è§æ€§ï¼ˆå¹¶ä¸”很å¯èƒ½åœ¨æ·»åŠ åŽéšè—它)。\n"
-"当你的æ’ä»¶åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨[method remove_control_from_container]删除你的自"
-"定义控件,并使用[method Node.queue_free]释放它。"
+"当你的æ’ä»¶åœç”¨æ—¶ï¼Œè¯·ç¡®ä¿ä½¿ç”¨ [method remove_control_from_container] 删除你的"
+"自定义控件,并使用 [method Node.queue_free] 释放它。"
#: doc/classes/EditorPlugin.xml
msgid ""
@@ -26644,10 +26756,13 @@ msgid ""
"To use [EditorSceneImporter], register it using the [method EditorPlugin."
"add_scene_import_plugin] method first."
msgstr ""
+"[EditorSceneImporter] å¯ç”¨äºŽå®šä¹‰ç¬¬ä¸‰æ–¹ 3D æ ¼å¼çš„导入脚本。\n"
+"è¦ä½¿ç”¨ [EditorSceneImporter],请先使用 [method EditorPlugin."
+"add_scene_import_plugin] 注册。"
#: modules/fbx/doc_classes/EditorSceneImporterFBX.xml
msgid "FBX 3D asset importer."
-msgstr "FBX 3D资产导入器。"
+msgstr "FBX 3D ç´ æå¯¼å…¥å™¨ã€‚"
#: modules/fbx/doc_classes/EditorSceneImporterFBX.xml
msgid ""
@@ -26676,8 +26791,8 @@ msgid ""
"- Binary format in FBX 2017\n"
"[/codeblock]"
msgstr ""
-"这是一个FBX 3D资产导入器,完全支æŒå¤§å¤šæ•°FBX功能。\n"
-"如果从Autodesk Maya导出一个FBX场景,请使用这些FBX导出设置:\n"
+"这是一个 FBX 3D ç´ æå¯¼å…¥å™¨ï¼Œå®Œå…¨æ”¯æŒå¤§å¤šæ•° FBX 功能。\n"
+"如果从 Autodesk Maya 导出一个 FBX 场景,请使用这些 FBX 导出设置:\n"
"[codeblock]\n"
"- Smoothing Groups 平滑化组\n"
"- Smooth Mesh 平滑网格\n"
@@ -27291,7 +27406,6 @@ msgid "Used by the editor to define Spatial gizmo types."
msgstr "由编辑部用于定义空间å°å·¥å…·çš„类型。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
-#, fuzzy
msgid ""
"[EditorSpatialGizmoPlugin] allows you to define a new type of Gizmo. There "
"are two main ways to do so: extending [EditorSpatialGizmoPlugin] for the "
@@ -27300,9 +27414,11 @@ msgid ""
"To use [EditorSpatialGizmoPlugin], register it using the [method "
"EditorPlugin.add_spatial_gizmo_plugin] method first."
msgstr ""
-"EditorSpatialGizmoPlugin å…è®¸æ‚¨å®šä¹‰ä¸€ç§æ–°çš„辅助工具类型。这样åšçš„ä¸»è¦æ–¹æ³•有两"
-"ç§ï¼šæ‰©å±• [EditorSpatialGizmoPlugin] 以获得更简å•çš„Gizmos,或创建新的 "
-"[EditorSpatialGizmoPlugin] 类型。有关更多信æ¯ï¼Œè¯·å‚阅文档中的教程。"
+"[EditorSpatialGizmoPlugin] å¯ç”¨äºŽå®šä¹‰æ–°çš„æŽ§åˆ¶å™¨ç±»åž‹ã€‚这样åšçš„ä¸»è¦æ–¹æ³•有两ç§ï¼š"
+"比较简å•的控制器å¯ä»¥æ‰©å±• [EditorSpatialGizmoPlugin],或者å¯ä»¥åˆ›å»ºæ–°çš„ "
+"[EditorSpatialGizmo] 类型。有关更多信æ¯ï¼Œè¯·å‚阅文档中的教程。\n"
+"è¦ä½¿ç”¨ [EditorSpatialGizmoPlugin],请先用 [method EditorPlugin."
+"add_spatial_gizmo_plugin] 注册。"
#: doc/classes/EditorSpatialGizmoPlugin.xml
msgid "$DOCS_URL/tutorials/plugins/editor/spatial_gizmos.html"
@@ -27465,20 +27581,23 @@ msgstr ""
"[EditorInspectorPlugin] ä¸€èµ·ä½¿ç”¨ï¼Œä»¥é‡æ–°åˆ›å»ºç›¸åŒçš„行为。"
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr "版本控制系统(VCS)接å£ï¼Œå¯å¯¹æ­£åœ¨ä½¿ç”¨çš„æœ¬åœ°VCS进行读写。"
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
msgstr ""
"由编辑器用æ¥åœ¨ç¼–辑器中显示VCSæå–的信æ¯ã€‚这个API的实现包å«åœ¨VCS附加组件中,这"
"些附加组件本质上是GDNativeæ’ä»¶ï¼Œéœ€è¦æ”¾åˆ°é¡¹ç›®æ–‡ä»¶å¤¹ä¸­ã€‚这些VCS附加组件是脚本,"
@@ -27487,129 +27606,242 @@ msgstr ""
"用的体验。"
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr "从列表中删除自动加载[code]name[/code]。"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
+msgstr "创建[code]class[/code]的实例。"
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
msgstr ""
-"如果add-onå·²ç»åˆå§‹åŒ–,则创建一个版本æäº¤ï¼Œå¦åˆ™ä¸åšä»»ä½•äº‹æƒ…å°±è¿”å›žã€‚ä½¿ç”¨ä¹‹å‰æš‚"
-"存的文件,æäº¤ä¿¡æ¯è®¾ç½®ä¸ºå‚数中æä¾›çš„值。"
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Discards the changes made in file present at [code]file_path[/code]."
+msgstr "将场景ä¿å­˜ä¸º[code]path[/code]处的文件。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
-msgstr ""
-"如果VCS addon被åˆå§‹åŒ–,返回一个[Array]çš„[Dictionary]å¯¹è±¡ï¼ŒåŒ…å«æ­£åœ¨ä½¿ç”¨çš„VCSçš„"
-"diff输出,å¦åˆ™è¿”回一个空[Array]对象。diff内容还包括一些上下文,这些上下文行为"
-"文件中观察到的行å˜åŒ–æä¾›ä¸Šä¸‹æ–‡ã€‚\n"
-"æ¯ä¸ª[Dictionary]对象的键下都有行差内容。\n"
-"- [code]\"content\"[/code]存储一个包å«è¡Œå†…容的[String]。\n"
-"- [code]\"status\"[/code]存储一个[String],如果内容是添加行,则包å«[code]\"+"
-"\"[/code],但如果是删除,则存储[code]\"-\"[/code]ï¼Œå¦‚æžœè¡Œå†…å®¹æ—¢ä¸æ˜¯æ·»åŠ ä¹Ÿä¸æ˜¯"
-"删除,则存储一个空字符串。\n"
-"- [code]\"new_line_number\"[/code]存储一个包å«è¡Œå†…容新行å·çš„æ•´æ•°ã€‚\n"
-"- [code]\"line_count\"[/code]存储一个整数,包å«è¡Œå†…容的行数。\n"
-"- [code]\"old_line_number\"[/code]存储包å«è¡Œå†…容的旧行å·çš„æ•´æ•°ã€‚\n"
-"- [code]\"offset\"[/code]存储自第一个上下文行内容以æ¥è¡Œå˜åŒ–çš„åç§»é‡ã€‚"
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
-msgstr ""
-"返回一个 [Dictionary]ï¼ŒåŒ…å«æ£€æµ‹åˆ°çš„æ›´æ”¹æ–‡ä»¶çš„路径,映射到一个整数,该整数表示"
-"相应文件更改的状æ€ã€‚\n"
-"以下整数值用于表示检测到的文件是:\n"
-"- [code]0[/code]:新的 VCS 工作目录\n"
-"- [code]1[/code]:修改\n"
-"- [code]2[/code]:é‡å‘½å\n"
-"- [code]3[/code]:删除\n"
-"- [code]4[/code]:类型改å˜"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Gets the current branch name defined in the VCS."
+msgstr "返回在[FileSystemDock]中查看的当å‰è·¯å¾„。"
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
-msgstr "返回VCS工作目录的项目å称。"
+msgid ""
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
-msgstr "如果VCSå·²ç»åˆå§‹åŒ–,返回VCSçš„å称,å¦åˆ™è¿”回一个空字符串。"
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
+msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
-"åˆå§‹åŒ–VCS addon(如果还未åˆå§‹åŒ–ï¼‰ã€‚ä½¿ç”¨å‚æ•°å€¼ä½œä¸ºé¡¹ç›®å·¥ä½œç›®å½•的路径。如果需"
-"è¦ï¼Œåˆ›å»ºåˆå§‹æäº¤ã€‚如果æˆåŠŸï¼Œè¿”å›ž[code]true[/code],å¦åˆ™è¿”回[code]false[/"
-"code]。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
-"如果addon准备好å“应函数调用,返回[code]true[/code],å¦åˆ™è¿”回[code]false[/"
-"code]。"
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
+msgstr "è¿”å›žåŒ…å«æ‰€æœ‰èŠ‚ç‚¹åç§°çš„[PoolStringArray]。"
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "返回[code]idx[/code]处的节点å称。"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
-"如果VCSæ’ä»¶å·²ç»åˆå§‹åŒ–,返回[code]true[/code],å¦åˆ™è¿”回[code]false[/code]。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a branch from the local VCS."
+msgstr "从选择中删除一个节点。"
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Remove a remote from the local VCS."
+msgstr "从选择中删除一个节点。"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr "å°†ç›¸æœºæº [code]feed[/code] æ·»åŠ åˆ°æ‘„åƒæœºæœåŠ¡å™¨ä¸­ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
msgstr ""
-"关闭VCSæ’件,å…许清ç†ä»£ç åŽ»è°ƒç”¨è¿è¡Œã€‚如果没有失败,返回[code]true[/code],å¦"
-"则返回[code]false[/code]。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
msgstr ""
-"调用[method EditorVCSInterface.commit]时应æäº¤çš„æ–‡ä»¶ã€‚傿•°åº”包å«ç»å¯¹è·¯å¾„。"
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Pops up an error message in the edior."
+msgstr "在编辑器中用于为属性分组。"
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A new file has been added."
+msgstr "æ·»åŠ æ–°æŽ¥å£æ—¶è§¦å‘。"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "A file is encountered from the staged area."
+msgstr "状æ€ï¼šä¸ŽæœåŠ¡å™¨æ–­å¼€è¿žæŽ¥ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
-"è§£é™¤ä¹‹å‰æš‚å­˜çš„è¦æäº¤çš„æ–‡ä»¶ï¼Œä»¥ä¾¿åœ¨è°ƒç”¨[method EditorVCSInterface.commit]æ—¶ä¸"
-"å†æäº¤ã€‚å‚æ•°åº”包å«ç»å¯¹è·¯å¾„。"
#: doc/classes/EncodedObjectAsID.xml
msgid "Holds a reference to an [Object]'s instance ID."
@@ -27940,7 +28172,6 @@ msgstr ""
"[member physics_jitter_fix]设置为[code]0[/code]æ¥ç¦ç”¨ç‰©ç†æŠ–动修å¤ã€‚"
#: doc/classes/Engine.xml
-#, fuzzy
msgid ""
"If [code]false[/code], stops printing error and warning messages to the "
"console and editor Output log. This can be used to hide error and warning "
@@ -27954,13 +28185,13 @@ msgid ""
"[b]Note:[/b] This property does not impact the editor's Errors tab when "
"running a project from the editor."
msgstr ""
-"如果 [code]false[/code]ï¼Œåœæ­¢æ‰“å°é”™è¯¯å’Œè­¦å‘Šä¿¡æ¯åˆ°æŽ§åˆ¶å°å’Œç¼–辑器输出日志。这å¯"
-"以用æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和警告信æ¯ã€‚这个属性等åŒäºŽ [member "
+"如果为 [code]false[/code]ï¼Œåˆ™åœæ­¢æ‰“å°é”™è¯¯å’Œè­¦å‘Šä¿¡æ¯åˆ°æŽ§åˆ¶å°å’Œç¼–辑器输出日志。"
+"è¿™å¯ä»¥ç”¨æ¥åœ¨å•元测试套件è¿è¡ŒæœŸé—´éšè—错误和警告信æ¯ã€‚这个属性等åŒäºŽ [member "
"ProjectSettings.application/run/disable_stderr] 项目设置。\n"
"[b]警告:[/b]如果你在项目的任æ„ä½ç½®å°†å…¶è®¾ç½®ä¸º [code]false[/code],é‡è¦çš„错误"
-"ä¿¡æ¯å¯èƒ½ä¼šè¢«éšè—,å³ä½¿å®ƒä»¬æ˜¯ç”±å…¶ä»–脚本触å‘。如果在 [code]@tool[/code] 脚本中"
-"把这个设置为 [code]false[/code],这也会影å“到编辑器本身。在确ä¿é”™è¯¯ä¿¡æ¯è¢«å¯ç”¨"
-"之å‰ï¼Œ[i]ä¸[/i]报告错误(默认情况下)。\n"
+"ä¿¡æ¯å¯èƒ½ä¼šè¢«éšè—,å³ä½¿å®ƒä»¬æ˜¯ç”±å…¶ä»–脚本触å‘。如果在 [code]tool[/code] 脚本中把"
+"这个设置为 [code]false[/code],这也会影å“到编辑器本身。在确ä¿é”™è¯¯ä¿¡æ¯è¢«å¯ç”¨ä¹‹"
+"å‰ï¼Œ[i]ä¸[/i]报告错误(默认情况下)。\n"
"[b]注æ„:[/b]当从编辑器è¿è¡Œä¸€ä¸ªé¡¹ç›®æ—¶ï¼Œè¿™ä¸ªå±žæ€§ä¸å½±å“编辑器的错误选项å¡ã€‚"
#: doc/classes/Engine.xml
@@ -29466,13 +29697,15 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
-"添加[code]filter[/code]作为自定义过滤器; [code]filter[/code]的格å¼åº”为"
-"[code]“ filename.extension; Descriptionâ€[/code]。例如,[code]\"*.png ; PNG "
-"Images\"[/code]。"
#: doc/classes/FileDialog.xml
msgid "Clear all the added filters in the dialog."
@@ -29535,10 +29768,13 @@ msgid "The currently selected file path of the file dialog."
msgstr "当å‰é€‰æ‹©çš„æ–‡ä»¶å¯¹è¯æ¡†çš„æ–‡ä»¶è·¯å¾„。"
#: doc/classes/FileDialog.xml
+#, fuzzy
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
"å¯ç”¨çš„æ–‡ä»¶ç±»åž‹è¿‡æ»¤å™¨ã€‚例如,这仅显示 [code].png[/code] å’Œ [code].gd[/code] æ–‡"
"件: [code]set_filters(PoolStringArray([\"*.png ; PNG Images\", \"*.gd ; "
@@ -29906,14 +30142,12 @@ msgstr ""
"个平å°å’Œæž¶æž„进行编译。"
#: modules/gdnative/doc_classes/GDNativeLibrary.xml
-#, fuzzy
msgid "$DOCS_URL/tutorials/scripting/gdnative/gdnative-c-example.html"
-msgstr "$DOCS_URL/tutorials/plugins/gdnative/gdnative-c-example.html"
+msgstr "$DOCS_URL/tutorials/scripting/gdnative/gdnative-c-example.html"
#: modules/gdnative/doc_classes/GDNativeLibrary.xml
-#, fuzzy
msgid "$DOCS_URL/tutorials/scripting/gdnative/gdnative-cpp-example.html"
-msgstr "$DOCS_URL/tutorials/plugins/gdnative/gdnative-cpp-example.html"
+msgstr "$DOCS_URL/tutorials/scripting/gdnative/gdnative-cpp-example.html"
#: modules/gdnative/doc_classes/GDNativeLibrary.xml
msgid ""
@@ -30006,9 +30240,8 @@ msgstr ""
"[method Object.set_script] 会扩展该对象。"
#: modules/gdscript/doc_classes/GDScript.xml
-#, fuzzy
msgid "$DOCS_URL/tutorials/scripting/gdscript/index.html"
-msgstr "$DOCS_URL/tutorials/scripting/index.html"
+msgstr "$DOCS_URL/tutorials/scripting/gdscript/index.html"
#: modules/gdscript/doc_classes/GDScript.xml
msgid "Returns byte code for the script source code."
@@ -30277,7 +30510,7 @@ msgstr "如果[code]true[/code],整个X轴的线性è¿åЍå—到é™åˆ¶ã€‚"
#: doc/classes/Generic6DOFJoint.xml
msgid "The minimum difference between the pivot points' X axis."
-msgstr "枢轴点的X轴之间的最å°å·®å¼‚。"
+msgstr "轴心点的 X 轴之间的最å°å·®å¼‚。"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -30293,7 +30526,7 @@ msgstr "应用于X轴上移动的一个系数。值越低,移动的就越慢ã€
#: doc/classes/Generic6DOFJoint.xml
msgid "The maximum difference between the pivot points' X axis."
-msgstr "枢轴点的X轴之间的最å°å·®å¼‚。"
+msgstr "轴心点的 X 轴之间的最大差异。"
#: doc/classes/Generic6DOFJoint.xml
msgid "The amount of damping that happens at the Y motion."
@@ -30305,7 +30538,7 @@ msgstr "如果[code]true[/code],é™åˆ¶è·¨è¶ŠY轴的线性è¿åŠ¨ã€‚"
#: doc/classes/Generic6DOFJoint.xml
msgid "The minimum difference between the pivot points' Y axis."
-msgstr "枢轴点的Y轴之间的最å°å·®å¼‚。"
+msgstr "轴心点的 Y 轴之间的最å°å·®å¼‚。"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -30321,7 +30554,7 @@ msgstr "应用于Y轴上移动的一个系数。值越低,移动的就越慢ã€
#: doc/classes/Generic6DOFJoint.xml
msgid "The maximum difference between the pivot points' Y axis."
-msgstr "枢轴点的Y轴之间的最大差异。"
+msgstr "轴心点的 Y 轴之间的最大差异。"
#: doc/classes/Generic6DOFJoint.xml
msgid "The amount of damping that happens at the Z motion."
@@ -30333,7 +30566,7 @@ msgstr "如果[code]true[/code],跨Z轴的线性è¿åЍå—到é™åˆ¶ã€‚"
#: doc/classes/Generic6DOFJoint.xml
msgid "The minimum difference between the pivot points' Z axis."
-msgstr "枢轴点的Z轴之间的最å°å·®å¼‚。"
+msgstr "轴心点的 Z 轴之间的最å°å·®å¼‚。"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -30349,7 +30582,7 @@ msgstr "适用于跨Z轴移动的一个系数。值越低,移动的就越慢ã€
#: doc/classes/Generic6DOFJoint.xml
msgid "The maximum difference between the pivot points' Z axis."
-msgstr "枢轴点的Z轴之间的最大差异。"
+msgstr "轴心点的 Z 轴之间的最大差异。"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -30407,11 +30640,11 @@ msgstr "线性马达在Z轴上试图达到的速度。"
#: doc/classes/Generic6DOFJoint.xml doc/classes/PhysicsServer.xml
msgid "The minimum difference between the pivot points' axes."
-msgstr "枢轴点之间的最å°å·®å¼‚。"
+msgstr "轴心点的轴之间的最å°å·®å¼‚。"
#: doc/classes/Generic6DOFJoint.xml doc/classes/PhysicsServer.xml
msgid "The maximum difference between the pivot points' axes."
-msgstr "枢轴点的轴之间的最大差异。"
+msgstr "轴心点的轴之间的最大差异。"
#: doc/classes/Generic6DOFJoint.xml
msgid ""
@@ -31634,6 +31867,102 @@ msgstr "将用于填充纹ç†çš„[Gradient]。"
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr "将从[Gradient]中获得的颜色样本的数é‡ã€‚"
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "Gradient-filled 2D texture."
+msgstr "æ¸å˜å¡«å……纹ç†ã€‚"
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+"GradientTexture使用[Gradient]æ¥å¡«å……çº¹ç†æ•°æ®ã€‚æ¸å˜å°†ä½¿ç”¨ä»Žä¸­èŽ·å¾—çš„é¢œè‰²ä»Žå·¦åˆ°å³"
+"填充。这æ„味ç€çº¹ç†ä¸ä¸€å®šä»£è¡¨æ¸å˜çš„精确副本,而是以固定的步长从æ¸å˜ä¸­èŽ·å¾—çš„æ ·"
+"本的æ’值,è§[member width]。"
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "将用于填充纹ç†çš„[Gradient]。"
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr "将从[Gradient]中获得的颜色样本的数é‡ã€‚"
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr "将从[Gradient]中获得的颜色样本的数é‡ã€‚"
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -32531,7 +32860,7 @@ msgstr "指定的 [MeshLibrary]。"
msgid ""
"Overrides the default friction and bounce physics properties for the whole "
"[GridMap]."
-msgstr ""
+msgstr "覆盖整个 [GridMap] 的默认摩擦力和å弹物ç†å±žæ€§ã€‚"
#: modules/gridmap/doc_classes/GridMap.xml
msgid ""
@@ -32792,7 +33121,6 @@ msgid "Used to create an HMAC for a message using a key."
msgstr "用æ¥ä¸ºä¸€ä¸ªä½¿ç”¨å¯†é’¥çš„ä¿¡æ¯åˆ›å»º HMAC。"
#: doc/classes/HMACContext.xml
-#, fuzzy
msgid ""
"The HMACContext class is useful for advanced HMAC use cases, such as "
"streaming the message as it supports creating the message over time rather "
@@ -32852,7 +33180,7 @@ msgstr ""
" var err = ctx.start(HashingContext.HASH_SHA256, key)\n"
" assert(err == OK)\n"
" var msg1 = \"this is \".to_utf8()\n"
-" var msg2 = \"vewy vewy secret\".to_utf8()\n"
+" var msg2 = \"super duper secret\".to_utf8()\n"
" err = ctx.update(msg1)\n"
" assert(err == OK)\n"
" err = ctx.update(msg2)\n"
@@ -32875,7 +33203,7 @@ msgstr ""
" Error err = ctx.Start(HashingContext.HASH_SHA256, key);\n"
" GD.Assert(err == OK);\n"
" PoolByteArray msg1 = String(\"this is \").to_utf8();\n"
-" PoolByteArray msg2 = String(\"vewy vew secret\").to_utf8();\n"
+" PoolByteArray msg2 = String(\"super duper secret\").to_utf8();\n"
" err = ctx.Update(msg1);\n"
" GD.Assert(err == OK);\n"
" err = ctx.Update(msg2);\n"
@@ -35811,7 +36139,6 @@ msgstr ""
"想è¦çš„值(在 0 到 1 的范围内)。"
#: doc/classes/Input.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] when the user starts pressing the action event, "
"meaning it's [code]true[/code] only on the frame that the user pressed down "
@@ -35826,13 +36153,16 @@ msgid ""
"[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
-"当用户开始按下动作事件时,返回[code]true[/code]ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œåªæœ‰åœ¨ç”¨æˆ·æŒ‰ä¸‹æŒ‰é’®"
-"çš„é‚£ä¸€å¸§æ‰æ˜¯[code]true[/code]。\n"
+"当用户开始按下动作事件时,返回 [code]true[/code]ï¼Œä¹Ÿå°±æ˜¯è¯´ï¼Œåªæœ‰åœ¨ç”¨æˆ·æŒ‰ä¸‹æŒ‰"
+"é’®çš„é‚£ä¸€å¸§æ‰æ˜¯ [code]true[/code]。\n"
"这对那些åªéœ€è¦åœ¨åŠ¨ä½œè¢«æŒ‰ä¸‹æ—¶è¿è¡Œä¸€æ¬¡çš„代ç ä¸­å¾ˆæœ‰ç”¨ï¼Œè€Œä¸æ˜¯åœ¨æŒ‰ä¸‹æ—¶æ¯ä¸€å¸§éƒ½è¦"
"è¿è¡Œã€‚\n"
-"如果[code]exact[/code]是[code]false[/code],它将忽略[InputEventKey]和"
-"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方"
-"å‘。"
+"如果 [code]exact[/code] 是 [code]false[/code],它将忽略 [InputEventKey] 和 "
+"[InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ [InputEventJoypadMotion] 事件"
+"的方å‘。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_just_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ª"
+"键按下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/"
+"inputs/input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/Input.xml
msgid ""
@@ -35850,7 +36180,6 @@ msgstr ""
"å‘。"
#: doc/classes/Input.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] if you are pressing the action event. Note that if "
"an action has multiple buttons assigned and more than one of them is "
@@ -35864,12 +36193,15 @@ msgid ""
"$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
-"如果你正在按下动作事件,返回[code]true[/code]。请注æ„,如果一个动作有多个分é…"
-"çš„æŒ‰é’®ï¼Œå¹¶ä¸”ä¸æ­¢ä¸€ä¸ªè¢«æŒ‰ä¸‹ï¼Œé‡Šæ”¾ä¸€ä¸ªæŒ‰é’®å°†é‡Šæ”¾è¿™ä¸ªåŠ¨ä½œï¼Œå³ä½¿å…¶ä»–分é…给这个动"
-"作的按钮ä»ç„¶è¢«æŒ‰ä¸‹ã€‚\n"
-"如果[code]exact[/code]是[code]false[/code],它将忽略[InputEventKey]和"
-"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方"
-"å‘。"
+"如果你正在按下动作事件,返回 [code]true[/code]。请注æ„,如果一个动作有多个分"
+"é…çš„æŒ‰é’®ï¼Œå¹¶ä¸”ä¸æ­¢ä¸€ä¸ªè¢«æŒ‰ä¸‹ï¼Œé‡Šæ”¾ä¸€ä¸ªæŒ‰é’®å°†é‡Šæ”¾è¿™ä¸ªåŠ¨ä½œï¼Œå³ä½¿å…¶ä»–分é…给这个"
+"动作的按钮ä»ç„¶è¢«æŒ‰ä¸‹ã€‚\n"
+"如果 [code]exact[/code] 是 [code]false[/code],它将忽略 [InputEventKey] 和 "
+"[InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ [InputEventJoypadMotion] 事件"
+"的方å‘。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰"
+"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/"
+"input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/Input.xml
msgid ""
@@ -35903,6 +36235,15 @@ msgid ""
"$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
+"如果你正在按当å‰é”®ç›˜å¸ƒå±€ä¸­çš„这个键,则返回 [code]true[/code]。å¯ä»¥ä¼  [enum "
+"KeyList] 常é‡ã€‚\n"
+"åªæœ‰éžæ¸¸æˆåº”用程åºä¸­æ‰æŽ¨è [method is_key_pressed] è€Œä¸æ˜¯ [method "
+"is_physical_key_pressed]。å¯ä»¥ç¡®ä¿å¿«æ·é”®çš„è¡Œä¸ºä¸Žç”¨æˆ·çš„é”®ç›˜å¸ƒå±€æœ‰å…³ï¼Œå› ä¸ºéžæ¸¸"
+"æˆåº”用程åºçš„键盘快æ·é”®é€šå¸¸ä¸Žé”®ç›˜å¸ƒå±€æœ‰å…³ã€‚如果有疑问,就请使用 [method "
+"is_physical_key_pressed]。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_key_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰ä¸‹æ—¶"
+"也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/"
+"input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/Input.xml
msgid ""
@@ -35926,6 +36267,15 @@ msgid ""
"[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
+"如果你正在按 101/102 é”®ç¾Žå¼ QWERTY 键盘中这个键的物ç†ä½ç½®ï¼Œåˆ™è¿”回 "
+"[code]true[/code]。å¯ä»¥ä¼  [enum KeyList] 常é‡ã€‚\n"
+"游æˆå†…的动作推è [method is_physical_key_pressed] è€Œä¸æ˜¯ [method "
+"is_key_pressed],因为å¯ä»¥è®© W/A/S/D 布局无论用户使用什么键盘布局都å¯ç”¨ã€‚"
+"[method is_physical_key_pressed] 还å¯ä»¥ä¿è¯é¡¶éƒ¨çš„æ•°å­—键在任何键盘布局中都å¯"
+"用。如果有疑问,就请使用 [method is_physical_key_pressed]。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_physical_key_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸ"
+"个键按下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/"
+"inputs/input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/Input.xml
msgid ""
@@ -36317,7 +36667,6 @@ msgstr ""
"å‘。"
#: doc/classes/InputEvent.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] if the given action is being pressed (and is not "
"an echo event for [InputEventKey] events, unless [code]allow_echo[/code] is "
@@ -36331,12 +36680,15 @@ msgid ""
"$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
-"如果给定的动作被按下,则返回[code]true[/code]ï¼Œå¹¶ä¸”ä¸æ˜¯ [InputEventKey] 事件"
-"çš„å›žæ˜¾äº‹ä»¶ï¼Œé™¤éž [code]allow_echo[/code] 是 [code]true[/code]。与"
-"[InputEventMouseMotion]或[InputEventScreenDrag]类型的事件无关。\n"
-"如果[code]exact_match[/code]是[code]false[/code],它将忽略[InputEventKey]和"
-"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方"
-"å‘。"
+"如果给定的动作被按下,则返回 [code]true[/code]ï¼Œå¹¶ä¸”ä¸æ˜¯ [InputEventKey] 事件"
+"çš„å›žæ˜¾äº‹ä»¶ï¼Œé™¤éž [code]allow_echo[/code] 是 [code]true[/code]。与 "
+"[InputEventMouseMotion] 或 [InputEventScreenDrag] 类型的事件无关。\n"
+"如果 [code]exact_match[/code] 是 [code]false[/code],它将忽略 "
+"[InputEventKey] å’Œ [InputEventMouseButton] äº‹ä»¶çš„è¾“å…¥ä¿®é¥°ç¬¦ï¼Œä»¥åŠ "
+"[InputEventJoypadMotion] 事件的方å‘。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰"
+"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/"
+"input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/InputEvent.xml
msgid ""
@@ -36358,18 +36710,17 @@ msgid ""
"Returns [code]true[/code] if this input event's type is one that can be "
"assigned to an input action."
msgstr ""
-"如果此输入事件的类型是å¯ä»¥åˆ†é…给输入动作的类型,则返回 [code]true[/code]。"
+"如果这个输入事件的类型是å¯ä»¥åˆ†é…给输入动作的类型,则返回 [code]true[/code]。"
#: doc/classes/InputEvent.xml
msgid ""
"Returns [code]true[/code] if this input event is an echo event (only for "
"events of type [InputEventKey])."
msgstr ""
-"如果此输入事件是回显事件(仅适用于 [InputEventKey] 类型的事件),则返回 "
+"如果这个输入事件是回显事件(仅适用于 [InputEventKey] 类型的事件),则返回 "
"[code]true[/code]。"
#: doc/classes/InputEvent.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] if this input event is pressed. Not relevant for "
"events of type [InputEventMouseMotion] or [InputEventScreenDrag].\n"
@@ -36378,11 +36729,11 @@ msgid ""
"$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input "
"examples[/url] in the documentation for more information."
msgstr ""
-"å¦‚æžœç»™å®šçš„åŠ¨ä½œè¢«é‡Šæ”¾ï¼Œå³æœªè¢«æŒ‰ä¸‹ï¼Œåˆ™è¿”回[code]true[/code]。与"
-"[InputEventMouseMotion]或[InputEventScreenDrag]类型的事件无关。\n"
-"如果[code]exact_match[/code]是[code]false[/code],它将忽略[InputEventKey]和"
-"[InputEventMouseButton]事件的输入修饰符,以åŠ[InputEventJoypadMotion]事件的方"
-"å‘。"
+"如果这个输入事件被按下,则返回 [code]true[/code]。与 [InputEventMouseMotion] "
+"或 [InputEventScreenDrag] 类型的事件无关。\n"
+"[b]注æ„:[/b]由于键盘冲çªï¼Œ[method is_action_pressed] å¯èƒ½ä¼šåœ¨åŠ¨ä½œçš„æŸä¸ªé”®æŒ‰"
+"下时也返回 [code]false[/code]。详情请å‚阅文档[url=$DOCS_URL/tutorials/inputs/"
+"input_examples.html#keyboard-events]《输入示例》[/url]。"
#: doc/classes/InputEvent.xml
msgid ""
@@ -36633,9 +36984,8 @@ msgstr ""
"set_ime_active]。"
#: doc/classes/InputEventMIDI.xml
-#, fuzzy
msgid "Input event for MIDI inputs."
-msgstr "动作的输入事件类型。"
+msgstr "MIDI 输入的输入事件。"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36650,26 +37000,34 @@ msgid ""
"Note that Godot does not currently support MIDI output, so there is no way "
"to emit MIDI signals from Godot. Only MIDI input works."
msgstr ""
+"InputEventMIDI å¯ä»¥å®žçŽ°ä»Žé’¢ç´ç­‰ MIDI 设备接收输入事件。MIDI 是 Musical "
+"Instrument Digital Interface 的缩写,å³éŸ³ä¹æ•°å­—接å£ã€‚\n"
+"MIDI ä¿¡å·å¯ä»¥é€šè¿‡ 5 é’ˆ MIDI 接头或 UDB 传输,如果你的设备两者都支æŒï¼Œè¯·ç¡®è®¤è¯¥"
+"设备的设置中正在使用的是哪一ç§è¾“出。\n"
+"è¦ä»Ž MIDI 设备接收输入事件,你需è¦è°ƒç”¨ [method OS.open_midi_inputs]。你å¯ä»¥ä½¿"
+"用 [method OS.get_connected_midi_inputs] 查看检测到的设备。\n"
+"è¯·æ³¨æ„ Godot ç›®å‰ä¸æ”¯æŒ MIDI 输出,因此无法从 Godot 中å‘出 MIDI ä¿¡å·ã€‚åªèƒ½è¿›"
+"行 MIDI 输入。"
#: doc/classes/InputEventMIDI.xml
msgid ""
"https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-"
"status-bytes"
msgstr ""
+"https://www.midi.org/specifications-old/item/table-2-expanded-messages-list-"
+"status-bytes"
#: doc/classes/InputEventMIDI.xml
-#, fuzzy
msgid "https://en.wikipedia.org/wiki/General_MIDI#Program_change_events"
msgstr ""
-"https://zh.wikipedia.org/zh-cn/%E5%96%AE%E7%B2%BE%E5%BA%A6%E6%B5%AE%E9%BB%9E"
-"%E6%95%B8"
+"https://zh.wikipedia.org/zh-cn/General_MIDI#%E9%9F%B3%E8%89%B2%E8%BD%89%E6%8F"
+"%9B%E4%BA%8B%E4%BB%B6%EF%BC%88Program_change_events%EF%BC%89"
#: doc/classes/InputEventMIDI.xml
-#, fuzzy
msgid "https://en.wikipedia.org/wiki/Piano_key_frequencies#List"
msgstr ""
-"https://zh.wikipedia.org/zh-cn/%E5%96%AE%E7%B2%BE%E5%BA%A6%E6%B5%AE%E9%BB%9E"
-"%E6%95%B8"
+"https://zh.wikipedia.org/zh-cn/%E9%8B%BC%E7%90%B4%E9%8D%B5%E9%A0%BB%E7%8E%87#"
+"%E5%88%97%E8%A1%A8"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36677,6 +37035,8 @@ msgid ""
"ranges from 0 to 15. MIDI channel 9 is reserved for the use with percussion "
"instruments, the rest of the channels are for non-percussion instruments."
msgstr ""
+"这个输入事件的 MIDI 通é“。总共有 16 个通é“,所以这个值的范围是 0 到 15。MIDI "
+"é€šé“ 9 是为打击ä¹å™¨ä¿ç•™çš„,其余通é“ä¾›éžæ‰“击ä¹å™¨ä½¿ç”¨ã€‚"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36684,6 +37044,8 @@ msgid ""
"the controller number, otherwise this is zero. Controllers include devices "
"such as pedals and levers."
msgstr ""
+"å¦‚æžœæ¶ˆæ¯æ˜¯ [code]MIDI_MESSAGE_CONTROL_CHANGE[/code],则表示控制器å·ï¼Œå¦åˆ™ä¸º"
+"零。控制器包å«è¸æ¿ã€æŽ¨æ†ç­‰è®¾å¤‡ã€‚"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36691,6 +37053,8 @@ msgid ""
"the controller value, otherwise this is zero. Controllers include devices "
"such as pedals and levers."
msgstr ""
+"å¦‚æžœæ¶ˆæ¯æ˜¯ [code]MIDI_MESSAGE_CONTROL_CHANGE[/code],则表示控制器值,å¦åˆ™ä¸º"
+"零。控制器包å«è¸æ¿ã€æŽ¨æ†ç­‰è®¾å¤‡ã€‚"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36700,11 +37064,15 @@ msgid ""
"every number on that chart. A standard piano will have an instrument number "
"of 0."
msgstr ""
+"这个输入事件的ä¹å™¨ã€‚这个值的范围是 0 到 127。ä¹å™¨åˆ—表请å‚考维基百科的 "
+"General MIDI 文中的ä¹å™¨åˆ—表,ä¸è¿‡è¿™ä¸ªå€¼æ˜¯ä»Ž 0 开始的,所以请把那张表中的数字"
+"都å‡ä¸€ã€‚标准钢ç´çš„ä¹å™¨å·ä¸º 0。"
#: doc/classes/InputEventMIDI.xml
+#, fuzzy
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -36715,6 +37083,14 @@ msgid ""
"For more information, see the MIDI message status byte list chart linked "
"above."
msgstr ""
+"返回表示这个 MIDI ä¿¡å·ç±»åž‹çš„值,是 MidiMessageList 枚举的æˆå‘˜ã€‚\n"
+"对于在 0x80 å’Œ 0xEF 之间的 MIDI 消æ¯ï¼Œè¿™ä¸ªå€¼è¿”回的是左åŠéƒ¨åˆ†çš„æ¯”特ä½ï¼Œå¦ä¸€åŠ"
+"是通é“(例:0x94 ä¼šå˜æˆ 0x9)。对于在 0xF0 到 0xFF 之间的 MIDI 消æ¯ï¼Œè¿™ä¸ªå€¼æ˜¯"
+"原样返回的。\n"
+"激活音符时会返回 [code]MIDI_MESSAGE_NOTE_ON[/code],但失活时并ä¸ä¸€å®šä¼šè¿”回 "
+"[code]MIDI_MESSAGE_NOTE_OFF[/code],因此你的代ç åº”该在ç»è¿‡ä¸€æ®µæ—¶é—´åŽå°†è¾“入处"
+"ç†ä¸ºåœæ­¢ã€‚\n"
+"更多消æ¯è¯·å‚阅上é¢é“¾æŽ¥çš„ MIDI 消æ¯çжæ€å­—节列表。"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36722,12 +37098,14 @@ msgid ""
"On a piano, middle C is 60, and A440 is 69, see the \"MIDI note\" column of "
"the piano key frequency chart on Wikipedia for more information."
msgstr ""
+"这个 MIDI ä¿¡å·çš„音调索引å·ã€‚这个值的范围为 0 到 127。在钢ç´ä¸Šï¼Œä¸­å¤® C 是 60,"
+"而 A440 是 69,更多信æ¯è¯·å‚阅维基百科钢ç´ç´é”®é¢‘率表的“MIDI 音符â€åˆ—。"
#: doc/classes/InputEventMIDI.xml
msgid ""
"The pressure of the MIDI signal. This value ranges from 0 to 127. For many "
"devices, this value is always zero."
-msgstr ""
+msgstr "MIDI ä¿¡å·çš„压力。这个值在 0 到 127 之间。对于很多设备,这个值总是 0。"
#: doc/classes/InputEventMIDI.xml
msgid ""
@@ -36735,6 +37113,8 @@ msgid ""
"piano, this corresponds to how quickly the key was pressed, and is rarely "
"above about 110 in practice."
msgstr ""
+"MIDI ä¿¡å·çš„速度。这个值在 0 到 127 之间。对于钢ç´ï¼Œè¿™å¯¹åº”的是按键有多å—,实际"
+"很少超过 110。"
#: doc/classes/InputEventMouse.xml
msgid "Base input event type for mouse events."
@@ -36751,25 +37131,24 @@ msgid ""
msgstr "é¼ æ ‡æŒ‰é’®æŽ©ç æ ‡è¯†ç¬¦ï¼Œæ˜¯[enum ButtonList] 按钮掩ç ä¹‹ä¸€æˆ–按ä½ç»„åˆã€‚"
#: doc/classes/InputEventMouse.xml
-#, fuzzy
msgid ""
"The global mouse position relative to the current [Viewport]. If used in "
"[method Control._gui_input] and if the current [Control] is not under the "
"mouse, moving it will not update this value."
msgstr ""
-"相对于[Viewport]的本地局部鼠标ä½ç½®ã€‚如果在[method Control._gui_input]中使用,"
-"ä½ç½®æ˜¯ç›¸å¯¹äºŽå½“å‰å¤„于鼠标下的控件[Control]。"
+"ç›¸å¯¹äºŽå½“å‰ [Viewport] 的全局鼠标ä½ç½®ã€‚如果在 [method Control._gui_input] 中使"
+"ç”¨ï¼Œå¹¶ä¸”å½“å‰ [Control] ä¸åœ¨é¼ æ ‡ä¹‹ä¸‹ï¼Œç§»åЍä¸ä¼šæ›´æ–°è¿™ä¸ªå€¼ã€‚"
#: doc/classes/InputEventMouse.xml
-#, fuzzy
msgid ""
"The local mouse position relative to the [Viewport]. If used in [method "
"Control._gui_input], the position is relative to the current [Control] which "
"is under the mouse. If the current [Control] is not under the mouse, moving "
"it will not update this value."
msgstr ""
-"相对于[Viewport]的本地局部鼠标ä½ç½®ã€‚如果在[method Control._gui_input]中使用,"
-"ä½ç½®æ˜¯ç›¸å¯¹äºŽå½“å‰å¤„于鼠标下的控件[Control]。"
+"ç›¸å¯¹äºŽå½“å‰ [Viewport] 的局部鼠标ä½ç½®ã€‚如果在 [method Control._gui_input] 中使"
+"用,该ä½ç½®æ˜¯ç›¸å¯¹äºŽé¼ æ ‡ä¹‹ä¸‹çš„å½“å‰ [Control] çš„ã€‚å¦‚æžœå½“å‰ [Control] ä¸åœ¨é¼ æ ‡ä¹‹"
+"下,移动ä¸ä¼šæ›´æ–°è¿™ä¸ªå€¼ã€‚"
#: doc/classes/InputEventMouseButton.xml
msgid "Input event type for mouse button events."
@@ -37062,7 +37441,7 @@ msgstr ""
#: doc/classes/InstancePlaceholder.xml
msgid "Placeholder for the root [Node] of a [PackedScene]."
-msgstr "[PackedScene] æ ¹ [Node] çš„å ä½ã€‚"
+msgstr "[PackedScene] æ ¹ [Node] çš„å ä½ç¬¦ã€‚"
#: doc/classes/InstancePlaceholder.xml
msgid ""
@@ -37077,18 +37456,18 @@ msgid ""
"a scene with a transform will transform children relatively to their parent "
"again."
msgstr ""
-"在编辑器中为实例化场景打开选项 [b]加载为å ä½ç¬¦[/b] 会导致在è¿è¡Œæ¸¸æˆæ—¶å°†å…¶æ›¿æ¢"
-"为实例å ä½ç¬¦[InstancePlaceholder]。这使得实际加载场景的时间å¯ä»¥æŽ¨è¿Ÿåˆ°è°ƒç”¨"
-"[method replace_by_instance]。这对于通过选择性加载部分场景æ¥é¿å…一次性加载大"
-"场景很有用。\n"
-"实例å ä½ç¬¦æ²¡æœ‰å˜æ¢(transform)属性。这导致任何å­èŠ‚ç‚¹ä»Žç‚¹ï¼ˆ0,0)开始相对于视窗"
-"进行定ä½ï¼Œè€Œä¸æ˜¯åœ¨ç¼–è¾‘å™¨ä¸­æ˜¾ç¤ºçš„çˆ¶èŠ‚ç‚¹ã€‚ç”¨ä¸€ä¸ªå…·æœ‰å˜æ¢å±žæ€§çš„åœºæ™¯æ¥æ›¿æ¢å ä½"
-"符,将使å­èŠ‚ç‚¹å†æ¬¡ç›¸å¯¹äºŽå®ƒä»¬çš„çˆ¶èŠ‚ç‚¹è¿›è¡Œå˜æ¢ã€‚"
+"在编辑器中为实例化的场景打开[b]加载为å ä½ç¬¦[/b]选项会导致在è¿è¡Œæ¸¸æˆæ—¶å°†å…¶æ›¿æ¢"
+"为 InstancePlaceholder。这样就å¯ä»¥å°†åœºæ™¯çš„实际加载推迟到调用 [method "
+"replace_by_instance] 时。这对于通过选择性加载部分场景æ¥é¿å…一次性加载大场景很"
+"有用。\n"
+"InstancePlaceholder ä¸å…·å¤‡å˜æ¢å±žæ€§ã€‚因此任何å­èŠ‚ç‚¹éƒ½ä¼šç›¸å¯¹äºŽ Viewport 从 (0, "
+"0) 点开始定ä½ï¼Œè€Œä¸æ˜¯åœ¨ç¼–è¾‘å™¨ä¸­æ˜¾ç¤ºçš„çˆ¶èŠ‚ç‚¹ã€‚ç”¨ä¸€ä¸ªå…·æœ‰å˜æ¢å±žæ€§çš„åœºæ™¯æ¥æ›¿æ¢å "
+"ä½ç¬¦ï¼Œå°†ä½¿å­èŠ‚ç‚¹å†æ¬¡ç›¸å¯¹äºŽå®ƒä»¬çš„çˆ¶èŠ‚ç‚¹è¿›è¡Œå˜æ¢ã€‚"
#: doc/classes/InstancePlaceholder.xml
msgid ""
"Not thread-safe. Use [method Object.call_deferred] if calling from a thread."
-msgstr "䏿˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用[method Object.call_deferred]。"
+msgstr "䏿˜¯çº¿ç¨‹å®‰å…¨çš„。如果从线程调用,请使用 [method Object.call_deferred]。"
#: doc/classes/InstancePlaceholder.xml
msgid ""
@@ -37106,9 +37485,9 @@ msgid ""
"loaded only if it's not loaded already. By manually loading the scene "
"beforehand, delays caused by this function can be avoided."
msgstr ""
-"ç”¨ä½œä¸ºå‚æ•°çš„场景替æ¢è¿™ä¸ªå ä½ç¬¦ï¼Œå¦‚æžœæ²¡æœ‰ç»™å‡ºå‚æ•°ï¼Œåˆ™æ›¿æ¢åŽŸå§‹åœºæ™¯ã€‚å¯¹äºŽæ‰€æœ‰çš„"
-"èµ„æºæ¥è¯´ï¼Œåªæœ‰å½“场景还没有被加载时æ‰ä¼šè¢«åŠ è½½ã€‚é€šè¿‡äº‹å…ˆæ‰‹åŠ¨åŠ è½½åœºæ™¯ï¼Œå¯ä»¥é¿å…"
-"由这个函数引起的延迟。"
+"ç”¨ä½œä¸ºå‚æ•°çš„场景替æ¢è¿™ä¸ªå ä½ç¬¦ï¼Œå¦‚æžœæ²¡æœ‰ç»™å‡ºå‚æ•°ï¼Œåˆ™ç”¨åŽŸå§‹åœºæ™¯æ›¿æ¢ã€‚与所有资"
+"æºç›¸åŒï¼Œåªæœ‰å½“场景还没有被加载时æ‰ä¼šè¢«åŠ è½½ã€‚é€šè¿‡äº‹å…ˆæ‰‹åŠ¨åŠ è½½åœºæ™¯ï¼Œå¯ä»¥é¿å…ç”±"
+"这个函数引起的延迟。"
#: doc/classes/int.xml
msgid "Integer built-in type."
@@ -37161,8 +37540,8 @@ msgid ""
"Cast a [bool] value to an integer value, [code]int(true)[/code] will be "
"equals to 1 and [code]int(false)[/code] will be equals to 0."
msgstr ""
-"将一个[bool]å€¼è½¬æ¢æˆä¸€ä¸ªæ•´æ•°å€¼ï¼Œ[code]int(true)[/code]将等于1,"
-"[code]int(false)[/code] 将等于0。"
+"å°† [bool] å€¼è½¬æ¢æˆæ•´æ•°å€¼ï¼Œ[code]int(true)[/code] 将等于 1,[code]int(false)[/"
+"code] 将等于 0。"
#: doc/classes/int.xml
msgid ""
@@ -38686,10 +39065,12 @@ msgid ""
"applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for "
"available behavior."
msgstr ""
+"è®¾ç½®ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶è¦åº”用的行为。为了达到物ç†å‡†ç¡®ï¼Œé»˜è®¤ä¼šåº”用你离开的最åŽä¸€ä¸ª"
+"å¹³å°çš„速度。å¯ç”¨çš„行为请å‚阅 [enum MovingPlatformApplyVelocityOnLeave] 常é‡ã€‚"
#: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml
msgid "Add the last platform velocity when you leave a moving platform."
-msgstr ""
+msgstr "ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶ï¼Œè¿½åŠ æœ€åŽä¸€ä¸ªå¹³å°çš„速度。"
#: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml
msgid ""
@@ -38697,15 +39078,16 @@ msgid ""
"downward motion is ignored. It's useful to keep full jump height even when "
"the platform is moving down."
msgstr ""
+"ç¦»å¼€ç§»åŠ¨å¹³å°æ—¶ï¼Œè¿½åŠ æœ€åŽä¸€ä¸ªå¹³å°çš„速度,但忽略å‘下的è¿åŠ¨ã€‚å¯ä»¥ç”¨æ¥åœ¨å¹³å°å‘下"
+"ç§»åŠ¨æ—¶ä¹Ÿä¿æŒå®Œæ•´çš„跳跃高度。"
#: doc/classes/KinematicBody.xml doc/classes/KinematicBody2D.xml
-#, fuzzy
msgid "Do nothing when leaving a platform."
-msgstr "使用 2D å˜æ¢æ—¶ä½¿ç”¨æ­¤é€‰é¡¹ã€‚"
+msgstr "ç¦»å¼€å¹³å°æ—¶ä»€ä¹ˆä¹Ÿä¸åšã€‚"
#: doc/classes/KinematicBody2D.xml
msgid "Kinematic body 2D node."
-msgstr "2Dè¿åŠ¨ä½“èŠ‚ç‚¹ã€‚"
+msgstr "2D è¿åŠ¨ä½“èŠ‚ç‚¹ã€‚"
#: doc/classes/KinematicBody2D.xml
msgid ""
@@ -41420,9 +41802,10 @@ msgid "Returns the number of faces in this [Mesh]."
msgstr "返回这个[Mesh]ä¸­çš„é¢æ•°ã€‚"
#: doc/classes/MeshDataTool.xml
+#, fuzzy
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
"返回与给定é¢å…³è”的指定边。\n"
"Edge傿•°å¿…é¡»å°äºŽç­‰äºŽ2,因为é¢åªæœ‰3æ¡è¾¹ã€‚"
@@ -41436,9 +41819,11 @@ msgid "Calculates and returns the face normal of the given face."
msgstr "计算并返回给定é¢çš„颿³•线。"
#: doc/classes/MeshDataTool.xml
+#, fuzzy
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
"返回给定é¢çš„æŒ‡å®šé¡¶ç‚¹ã€‚\n"
"é¡¶ç‚¹å‚æ•°å¿…é¡»å°äºŽç­‰äºŽ2,因为é¢åŒ…å«3个顶点。"
@@ -41695,9 +42080,10 @@ msgid "The [Mesh] that will be drawn by the [MeshInstance2D]."
msgstr "[Mesh]将由[MeshInstance2D]绘制。"
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
+#, fuzzy
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -42553,7 +42939,6 @@ msgid "Mesh-based navigation and pathfinding node."
msgstr "基于网格的导航和寻路节点。"
#: doc/classes/Navigation.xml
-#, fuzzy
msgid ""
"Provides navigation and pathfinding within a collection of "
"[NavigationMesh]es. By default, these will be automatically collected from "
@@ -42561,11 +42946,9 @@ msgid ""
"class also assists with aligning navigation agents with the meshes they are "
"navigating on."
msgstr ""
-"在[NavigationMesh]的集åˆä¸­æä¾›å¯¼èˆªå’Œå¯»è·¯åŠŸèƒ½ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›å°†è‡ªåŠ¨ä»Žå­"
-"[NavigationMeshInstance]节点中收集,也å¯ä»¥é€šè¿‡[method navmesh_add]峿—¶æ·»åŠ ã€‚"
-"除了基本的寻路之外,这个类还能帮助导航代ç†ä¸Žå…¶æ‰€å¯¼èˆªçš„网格对é½ã€‚\n"
-"[b]注æ„:[/b] ç›®å‰çš„å¯¼èˆªç³»ç»Ÿæœ‰è®¸å¤šå·²çŸ¥çš„é—®é¢˜ï¼Œå¹¶ä¸æ€»æ˜¯èƒ½åƒé¢„期的那样返回最佳"
-"路径。这些问题将在Godot 4.0中得到解决。"
+"在 [NavigationMesh] 的集åˆä¸­æä¾›å¯¼èˆªå’Œå¯»è·¯åŠŸèƒ½ã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›å°†è‡ªåŠ¨ä»Žå­ "
+"[NavigationMeshInstance] 节点中收集,也å¯ä»¥é€šè¿‡ [method navmesh_add] 峿—¶æ·»"
+"加。除了基本的寻路之外,这个类还能帮助导航代ç†ä¸Žå…¶æ‰€å¯¼èˆªçš„网格对é½ã€‚"
#: doc/classes/Navigation.xml doc/classes/NavigationMesh.xml
#: doc/classes/NavigationServer.xml
@@ -42588,14 +42971,12 @@ msgstr ""
"代ç†ã€‚"
#: doc/classes/Navigation.xml
-#, fuzzy
msgid ""
"Returns the owner of the [NavigationMesh] which contains the navigation "
"point closest to the point given. This is usually a [NavigationMeshInstance]."
msgstr ""
"è¿”å›žåŒ…å«æœ€æŽ¥è¿‘给定点的导航点的 [NavigationMesh] 的所有者。这通常是一个 "
-"[NavigationMeshInstance]。对于通过 [method navmesh_add] 添加的网格,返回给定"
-"的所有者(如果çœç•¥ [code]owner[/code] 傿•°ï¼Œåˆ™è¿”回 [code]null[/code])。"
+"[NavigationMeshInstance]。"
#: doc/classes/Navigation.xml
msgid ""
@@ -42608,18 +42989,15 @@ msgstr ""
"导航网格之间的交点。如果找到多个交点,则返回最接近线段起点的交点。"
#: doc/classes/Navigation.xml
-#, fuzzy
msgid ""
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the "
"agent properties associated with each [NavigationMesh] (radius, height, "
"etc.) are considered in the path calculation, otherwise they are ignored."
msgstr ""
-"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­ã€‚如果[code]optimize[/code]是"
-"[code]true[/code](默认),与æ¯ä¸ª[NavigationMesh]相关的代ç†å±žæ€§ï¼ˆåŠå¾„ã€é«˜åº¦"
-"等)在路径计算中被考虑,å¦åˆ™å…¶è¢«å¿½ç•¥ã€‚\n"
-"[b]注æ„:[/b] 这个方法有已知的问题,ç»å¸¸ä¼šè¿”å›žéžæœ€ä½³çš„路径。这些问题将在"
-"Godot 4.0中得到修正。"
+"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­ã€‚如果 [code]optimize[/code] "
+"是 [code]true[/code](默认),与æ¯ä¸ª [NavigationMesh] 相关的代ç†å±žæ€§ï¼ˆåŠå¾„ã€"
+"高度等)在路径计算中被考虑,å¦åˆ™å…¶è¢«å¿½ç•¥ã€‚"
#: doc/classes/Navigation.xml doc/classes/NavigationMesh.xml
msgid "The XZ plane cell size to use for fields."
@@ -42628,7 +43006,7 @@ msgstr "用于字段的XZå¹³é¢å•元尺寸。"
#: doc/classes/Navigation.xml doc/classes/Navigation2D.xml
msgid ""
"This value is used to detect the near edges to connect compatible regions."
-msgstr ""
+msgstr "该值用于检测相近的边界,连接兼容的地区。"
#: doc/classes/Navigation.xml
msgid ""
@@ -42640,20 +43018,17 @@ msgstr ""
#: doc/classes/Navigation2D.xml
msgid "2D navigation and pathfinding node."
-msgstr "2D导航和寻路节点。"
+msgstr "2D 导航和寻路节点。"
#: doc/classes/Navigation2D.xml
-#, fuzzy
msgid ""
"Navigation2D provides navigation and pathfinding within a 2D area, specified "
"as a collection of [NavigationPolygon] resources. By default, these are "
"automatically collected from child [NavigationPolygonInstance] nodes."
msgstr ""
-"Navigation2D在2D区域内æä¾›å¯¼èˆªå’Œå¯»è·¯ï¼ŒæŒ‡å®šä¸º[NavigationPolygon]资æºçš„集åˆã€‚默"
-"认情况下,这些资æºè‡ªåŠ¨ä»Žå­[NavigationPolygonInstance]节点中收集,但其也å¯ä»¥é€š"
-"过[method navpoly_add]峿—¶æ·»åŠ ã€‚\n"
-"[b]注æ„:[/b] 当å‰çš„å¯¼èˆªç³»ç»Ÿæœ‰è®¸å¤šå·²çŸ¥çš„é—®é¢˜ï¼Œå¹¶ä¸æ€»æ˜¯èƒ½åƒé¢„期的那样返回最佳"
-"的路径。这些问题将在Godot 4.0中得到解决。"
+"Navigation2D 在 2D 区域内æä¾›å¯¼èˆªå’Œå¯»è·¯ï¼Œè¯¥åŒºåŸŸä»¥ [NavigationPolygon] 资æºåˆ"
+"é›†çš„å½¢å¼æŒ‡å®šã€‚é»˜è®¤æƒ…å†µä¸‹ï¼Œè¿™äº›èµ„æºæ˜¯è‡ªåŠ¨ä»Žå­é¡¹ [NavigationPolygonInstance] 节"
+"点中收集的。"
#: doc/classes/Navigation2D.xml doc/classes/Navigation2DServer.xml
#: doc/classes/NavigationPolygon.xml
@@ -42661,37 +43036,30 @@ msgid "https://godotengine.org/asset-library/asset/117"
msgstr "https://godotengine.org/asset-library/asset/117"
#: doc/classes/Navigation2D.xml
-#, fuzzy
msgid ""
"Returns the owner of the [NavigationPolygon] which contains the navigation "
"point closest to the point given. This is usually a "
"[NavigationPolygonInstance]."
msgstr ""
"è¿”å›žåŒ…å«æœ€æŽ¥è¿‘给定点的导航点的 [NavigationPolygon] 的所有者。这通常是一个 "
-"[NavigationPolygonInstance]。对于通过 [method navpoly_add] 添加的多边形,返回"
-"给定的所有者(如果çœç•¥ [code]owner[/code] 傿•°ï¼Œåˆ™è¿”回 [code]null[/code])。"
+"[NavigationPolygonInstance]。"
#: doc/classes/Navigation2D.xml
-#, fuzzy
msgid ""
"Returns the path between two given points. Points are in local coordinate "
"space. If [code]optimize[/code] is [code]true[/code] (the default), the path "
"is smoothed by merging path segments where possible."
msgstr ""
-"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­ã€‚如果[code]optimize[/code]为"
-"[code]true[/code](默认值),路径将尽å¯èƒ½åœ°åˆå¹¶è·¯å¾„段,从而平滑。\n"
-"[b]注æ„:[/b] 这个方法有已知的问题,ç»å¸¸ä¼šè¿”å›žéžæœ€ä½³çš„路径。这些问题将在"
-"Godot 4.0中得到解决。"
+"è¿”å›žä¸¤ä¸ªç»™å®šç‚¹ä¹‹é—´çš„è·¯å¾„ã€‚ç‚¹æ˜¯åœ¨å±€éƒ¨åæ ‡ç©ºé—´ä¸­ã€‚如果 [code]optimize[/code] "
+"为 [code]true[/code](默认值),路径将尽å¯èƒ½åœ°åˆå¹¶è·¯å¾„段,从而平滑。"
#: doc/classes/Navigation2D.xml
-#, fuzzy
msgid "The XY plane cell size to use for fields."
-msgstr "用于字段的XZå¹³é¢å•元尺寸。"
+msgstr "用于字段的 XZ å¹³é¢å•元尺寸。"
#: doc/classes/Navigation2DServer.xml
-#, fuzzy
msgid "Server interface for low-level 2D navigation access."
-msgstr "低级音频访问的æœåŠ¡å™¨æŽ¥å£ã€‚"
+msgstr "访问底层 2D 导航的æœåŠ¡å™¨æŽ¥å£ã€‚"
#: doc/classes/Navigation2DServer.xml
msgid ""
@@ -42714,25 +43082,34 @@ msgid ""
"phase. This means that you can request any change to the map, using any "
"thread, without worrying."
msgstr ""
+"Navigation2DServer 是负责所有 2D 导航的æœåŠ¡å™¨ï¼Œå¤„ç†çš„对象有地图(map)ã€åœ°åŒº"
+"(region)ã€ä»£ç†ï¼ˆagent)。\n"
+"地图是由地区组æˆçš„,地区åˆç”±å¯¼èˆªå¤šè¾¹å½¢ç»„æˆã€‚å®ƒä»¬ä¸€åŒæž„æˆäº† 2D 世界中的å¯å¯¼èˆª"
+"区域。两个地区必须共有一æ¡ç›¸ä¼¼çš„边界(edge)æ‰èƒ½ç›¸è¿žã€‚如果一æ¡è¾¹ç•Œçš„两个顶点"
+"(vertex)与å¦ä¸€æ¡è¾¹ç•Œçš„对应顶点的è·ç¦»å°äºŽ [member Navigation."
+"edge_connection_margin],则认为这两æ¡è¾¹ç•Œç›¸è¿žã€‚\n"
+"è¦ä½¿ç”¨é˜²æ’žç³»ç»Ÿï¼Œå¯ä»¥ä½¿ç”¨ä»£ç†ã€‚ä½ å¯ä»¥è®¾ç½®ä»£ç†çš„目标速度,æœåŠ¡å™¨å°±ä¼šä½¿ç”¨ä¿®æ­£åŽ"
+"的速度触å‘回调。\n"
+"[b]注æ„:[/b]防撞系统会忽略地区。直接使用修正åŽçš„速度å¯èƒ½ä¼šå°†ä»£ç†æŽ¨åˆ°å¯å¯¼èˆªåŒº"
+"åŸŸä¹‹å¤–ã€‚è¿™æ˜¯é˜²æ’žç³»ç»Ÿçš„ç¼ºé™·ï¼Œæ›´å¤æ‚的情况å¯èƒ½éœ€è¦ç”¨åˆ°ç‰©ç†å¼•擎。\n"
+"æœåŠ¡å™¨ä¼šè®°å½•æ‰€æœ‰çš„è°ƒç”¨ï¼Œåœ¨åŒæ­¥é˜¶æ®µç»Ÿä¸€æ‰§è¡Œã€‚è¿™æ„味ç€ä½ å¯ä»¥æ”¾å¿ƒå¤§èƒ†åœ°ä»Žä»»ä½•线"
+"程中请求对地图进行任何修改。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Creates the agent."
-msgstr "创建一个 [HingeJoint]关节。"
+msgstr "创建代ç†ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Returns [code]true[/code] if the map got changed the previous frame."
-msgstr "如果脚本å¯ä»¥å®žä¾‹åŒ–,则返回 [code]true[/code]。"
+msgstr "如果地图在上一帧å‘生了改å˜ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid "Callback called at the end of the RVO process."
-msgstr ""
+msgstr "在 RVO å¤„ç†æœ«å°¾è°ƒç”¨çš„回调。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Puts the agent in the map."
-msgstr "返回输入的正切值。"
+msgstr "å°†ä»£ç†æ”¾å…¥åœ°å›¾ä¸­ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
@@ -42740,11 +43117,12 @@ msgid ""
"navigation. The larger this number, the longer the running time of the "
"simulation. If the number is too low, the simulation will not be safe."
msgstr ""
+"è®¾ç½®åœ¨å¯¼èˆªä¸­ï¼Œè¯¥ä»£ç†æ‰€è€ƒè™‘的其他代ç†çš„æœ€å¤§æ•°é‡ã€‚这个数越大,模拟的è¿è¡Œæ—¶é—´è¶Š"
+"长。如果这个数太å°ï¼Œåˆ™æ¨¡æ‹Ÿä¼šä¸å®‰å…¨ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the maximum speed of the agent. Must be positive."
-msgstr "设置自动图å—çš„[enum BitmaskMode]ä½æŽ©ç æ¨¡å¼ã€‚"
+msgstr "设置该代ç†çš„æœ€å¤§é€Ÿåº¦ã€‚必须为正数。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
@@ -42752,21 +43130,20 @@ msgid ""
"the navigation. The larger this number, the longer the running time of the "
"simulation. If the number is too low, the simulation will not be safe."
msgstr ""
+"è®¾ç½®åœ¨å¯¼èˆªä¸­ï¼Œè¯¥ä»£ç†æ‰€è€ƒè™‘的其他代ç†çš„æœ€å¤§è·ç¦»ã€‚这个数越大,模拟的è¿è¡Œæ—¶é—´è¶Š"
+"长。如果这个数太å°ï¼Œåˆ™æ¨¡æ‹Ÿä¼šä¸å®‰å…¨ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the position of the agent in world space."
-msgstr "设置给定顶点的ä½ç½®ã€‚"
+msgstr "设置该代ç†åœ¨ä¸–界空间中的ä½ç½®ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the radius of the agent."
-msgstr "设置给定顶点的法线。"
+msgstr "设置该代ç†çš„åŠå¾„。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the new target velocity."
-msgstr "设置给定顶点的骨架。"
+msgstr "设置新的目标速度。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
@@ -42776,96 +43153,84 @@ msgid ""
"agents, but the less freedom this agent has in choosing its velocities. Must "
"be positive."
msgstr ""
+"考虑其他代ç†çš„å‰æä¸‹ï¼Œè¯¥ä»£ç†çš„速度的最短安全时间,这个速度是通过模拟得到的。"
+"这个数越大,该代ç†å“应其他代ç†çš„速度越快,但该代ç†é€‰æ‹©é€Ÿåº¦çš„自由度也越å°ã€‚å¿…"
+"须为正数。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the current velocity of the agent."
-msgstr "è¿”å›žè¡¥é—´çš„å½“å‰æ—¶é—´ã€‚"
+msgstr "设置该代ç†çš„当å‰é€Ÿåº¦ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Destroys the given RID."
-msgstr "ç§»é™¤ç»™å®šçš„å›¾å— ID。"
+msgstr "销æ¯ç»™å®šçš„ RID。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Create a new map."
-msgstr "创建一个[Area]区域。"
+msgstr "创建一张新地图。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Returns the map cell size."
-msgstr "返回数组大å°ã€‚"
+msgstr "返回地图的å•元格大å°ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid ""
"Returns the point closest to the provided [code]to_point[/code] on the "
"navigation mesh surface."
-msgstr ""
-"返回索引[code]point[/code]处的点在索引[code]triangle[/code]的三角形中的ä½ç½®ã€‚"
+msgstr "返回在导航网格表é¢ä¸Šä¸Žæä¾›çš„ [code]to_point[/code] è·ç¦»æœ€è¿‘的点。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid ""
"Returns the owner region RID for the point returned by [method "
"map_get_closest_point]."
-msgstr "返回正在使用的输入端å£çš„æ•°é‡ã€‚替代[method get_free_input_port_id]。"
+msgstr "返回由 [method map_get_closest_point] 返回的点的所有者地区的 RID。"
#: doc/classes/Navigation2DServer.xml
msgid ""
"Returns the edge connection margin of the map. The edge connection margin is "
"a distance used to connect two regions."
-msgstr ""
+msgstr "返回地图的边界连接边è·ã€‚è¾¹ç•Œè¿žæŽ¥è¾¹è·æ˜¯ç”¨äºŽè¿žæŽ¥ä¸¤ä¸ªåœ°åŒºçš„è·ç¦»ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Returns the navigation path to reach the destination from the origin."
-msgstr "返回图å—的导航多边形。"
+msgstr "返回从原点到终点的导航路径。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Returns [code]true[/code] if the map is active."
-msgstr "如果选择处于活动状æ€ï¼Œåˆ™è¿”回 [code]true[/code]。"
+msgstr "如果地图处于活动状æ€ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the map active."
-msgstr "åœæ­¢å®šæ—¶å™¨ã€‚"
+msgstr "设置地图的激活æ€ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Set the map cell size used to weld the navigation mesh polygons."
-msgstr "返回应用于该项导航网格的转æ¢ã€‚"
+msgstr "设置用于焊接导航网格多边形的地图å•元格大å°ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
msgid ""
"Set the map edge connection margin used to weld the compatible region edges."
-msgstr ""
+msgstr "设置用于焊接兼容地区边界的地图边界连接边è·ã€‚"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Creates a new region."
-msgstr "创建一个[Area]区域。"
+msgstr "创建一个新的地区。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the map for the region."
-msgstr "设置给定边的元数æ®ã€‚"
+msgstr "设置该地区的地图。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the navigation mesh for the region."
-msgstr "设置此项的导航网格。"
+msgstr "设置该地图的导航网格。"
#: doc/classes/Navigation2DServer.xml doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the global transformation for the region."
-msgstr "è®¾ç½®è§†çª—çš„å…¨å±€å˜æ¢çŸ©é˜µã€‚"
+msgstr "è®¾ç½®è¯¥åœ°åŒºçš„å…¨å±€å˜æ¢ã€‚"
#: doc/classes/NavigationAgent.xml
msgid "3D agent used in navigation for collision avoidance."
-msgstr ""
+msgstr "在导航中用于防撞的 3D 代ç†ã€‚"
#: doc/classes/NavigationAgent.xml
msgid ""
@@ -42876,6 +43241,10 @@ msgid ""
"child of a [Navigation] node, or using [method set_navigation]. "
"[NavigationAgent] is physics safe."
msgstr ""
+"导航中使用的 3D 代ç†ï¼Œå¯ä»¥åœ¨å‰å¾€æŸä¸ªä½ç½®æ—¶èº²é¿é™æ€å’ŒåЍæ€éšœç¢ç‰©ã€‚躲é¿åЍæ€éšœç¢"
+"物使用的是 RVO(Reciprocal Velocity Obstacles,相对速度障ç¢ç‰©ï¼‰é˜²æ’žç®—法。代ç†"
+"需è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ­£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©ä»£ç†æˆä¸º [Navigation] 节点的å­é¡¹å®žçŽ°ï¼Œä¹Ÿ"
+"å¯ä»¥ä½¿ç”¨ [method set_navigation]。[NavigationAgent] 是物ç†å®‰å…¨çš„。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -42883,32 +43252,33 @@ msgid ""
"position. The user must set the target location with [method "
"set_target_location] in order for this to be accurate."
msgstr ""
+"返回与目标ä½ç½®çš„è·ç¦»ï¼Œä½¿ç”¨çš„æ˜¯ä»£ç†çš„全局ä½ç½®ã€‚用户必须使用 [method "
+"set_target_location] 设置目标ä½ç½®ï¼Œæ‰èƒ½èŽ·å¾—ç²¾ç¡®ç»“æžœã€‚"
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
"best to check this each frame."
msgstr ""
+"返回å¯åˆ°è¾¾çš„æœ€ç»ˆä½ç½®çš„免局忠‡ã€‚如果导航路径由于任何原因å‘生改å˜ï¼Œè¿™ä¸ªä½ç½®ä¹Ÿ"
+"å¯èƒ½å‘生å˜åŒ–。因此,最好æ¯ä¸€å¸§éƒ½æ£€æŸ¥ä¸€ä¸‹ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "Returns the path from start to finish in global coordinates."
-msgstr "返回全局å±å¹•åæ ‡ä¸­çš„å¯è§çŸ©å½¢ã€‚"
+msgstr "è¿”å›žä»Žèµ·ç‚¹åˆ°ç»ˆç‚¹çš„è·¯å¾„ï¼Œä½¿ç”¨å…¨å±€åæ ‡ã€‚"
#: doc/classes/NavigationAgent.xml
-#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector3Array]."
-msgstr "以 [PoolVector3Array] 的形å¼è¿”回缓存的点。"
+msgstr "返回该代ç†å½“å‰ä½äºŽå¯¼èˆªè·¯å¾„ [PoolVector3Array] 中的哪个索引ä½ç½®ã€‚"
#: doc/classes/NavigationAgent.xml
-#, fuzzy
msgid ""
"Returns the [Navigation] node that the agent is using for its navigation "
"system."
-msgstr "返回指定å称的动画节点。"
+msgstr "返回该代ç†çš„导航系统所使用的 [Navigation] 节点。"
#: doc/classes/NavigationAgent.xml
msgid ""
@@ -42916,28 +43286,28 @@ msgid ""
"that there are no static objects in the way. If the agent does not have a "
"navigation path, it will return the origin of the agent's parent."
msgstr ""
+"返回å¯ä»¥ç§»åŠ¨è‡³çš„ [Vector3] 免局忠‡ï¼Œç¡®ä¿ä¸­é€”æ²¡æœ‰é™æ€ç‰©ä½“é˜»æŒ¡ã€‚å¦‚æžœä»£ç†æ²¡æœ‰å¯¼"
+"航路径,则会返回代ç†çˆ¶èŠ‚ç‚¹çš„åŽŸç‚¹ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid ""
"Returns the user-defined target location (set with [method "
"set_target_location])."
-msgstr "返回用[method set_size_override]设置的尺寸é‡å†™ã€‚"
+msgstr "返回用户定义的目标ä½ç½®ï¼ˆä½¿ç”¨ [method set_target_location] 设置)。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] if the navigation path's final location has been "
"reached."
-msgstr "返回[code]true[/code]是å¦å¯¹æŒ‡å®šè·¯å¾„进行过滤。"
+msgstr "如果到达了导航路径的终点ä½ç½®ï¼Œåˆ™è¿”回 [code]true[/code]。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid ""
"Returns [code]true[/code] if the target location is reachable. The target "
"location is set using [method set_target_location]."
msgstr ""
-"如果å¯ç”¨äº†å°ºå¯¸é‡å†™ï¼Œè¿”回[code]true[/code]。å‚阅[method set_size_override]。"
+"如果目标ä½ç½®å¯è¾¾ï¼Œåˆ™è¿”回 [code]true[/code]。目标ä½ç½®ä½¿ç”¨ [method "
+"set_target_location] 设置。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -42946,51 +43316,54 @@ msgid ""
"possible to reach the target location. It should always be possible to reach "
"the final location though. See [method get_final_location]."
msgstr ""
+"如果已到达目标ä½ç½®ï¼Œåˆ™è¿”回 [code]true[/code]。目标ä½ç½®ä½¿ç”¨ [method "
+"set_target_location] 设置。目标ä½ç½®å¹¶ä¸æ€»æ˜¯å¯è¾¾ã€‚但终点ä½ç½®åº”该总是å¯è¾¾çš„。请"
+"å‚阅 [method get_final_location]。"
#: doc/classes/NavigationAgent.xml
msgid ""
"Sets the [Navigation] node used by the agent. Useful when you don't want to "
"make the agent a child of a [Navigation] node."
msgstr ""
+"è®¾ç½®ä»£ç†æ‰€ä½¿ç”¨çš„ [Navigation] 节点。å¯ä»¥åœ¨ä½ ä¸æƒ³è®©ä»£ç†ä½œä¸º [Navigation] 节点"
+"çš„å­èŠ‚ç‚¹æ—¶ä½¿ç”¨ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Sets the user desired final location. This will clear the current navigation "
"path."
-msgstr ""
+msgstr "设置用户期望的终点ä½ç½®ã€‚会将当å‰å¯¼èˆªè·¯å¾„清空。"
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
+"将传入的速度å‘é€ç»™é˜²æ’žç®—法。算法会为了防止撞击而调整速度。速度的调整完æˆåŽï¼Œ"
+"ä¼šè§¦å‘ [signal velocity_computed] ä¿¡å·ã€‚"
#: doc/classes/NavigationAgent.xml
-#, fuzzy
msgid "The agent height offset to match the navigation mesh height."
-msgstr "返回图å—的导航多边形的åç§»é‡ã€‚"
+msgstr "代ç†çš„高度åç§»é‡ï¼Œç”¨äºŽåŒ¹é…导航网格的高度。"
#: doc/classes/NavigationAgent.xml
msgid ""
"Ignores collisions on the Y axis. Must be [code]true[/code] to move on a "
"horizontal plane."
-msgstr ""
+msgstr "忽略 Y 轴上的碰撞。在水平é¢ä¸Šç§»åŠ¨æ—¶å¿…é¡»ä¸º [code]true[/code]。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "The maximum number of neighbors for the agent to consider."
-msgstr "自动æ›å…‰çš„æœ€å¤§äº®åº¦å€¼ã€‚"
+msgstr "ä»£ç†æ‰€éœ€è€ƒè™‘的最大邻居数。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "The maximum speed that an agent can move."
-msgstr "曲线能达到的最大值。"
+msgstr "ä»£ç†æ‰€èƒ½è¾¾åˆ°çš„æœ€å¤§ç§»åŠ¨é€Ÿåº¦ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "The distance to search for other agents."
-msgstr "实例没有类型。"
+msgstr "æœç´¢å…¶ä»–代ç†çš„è·ç¦»ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -42998,11 +43371,12 @@ msgid ""
"final location. This can happen due to trying to avoid collisions. When the "
"maximum distance is exceeded, it recalculates the ideal path."
msgstr ""
+"å…许代ç†åç¦»ç†æƒ³è·¯å¾„的最大è·ç¦»ã€‚å¯èƒ½ä¸ºäº†é˜²æ’žè€Œäº§ç”Ÿå离。超出最大è·ç¦»æ—¶ï¼Œä¼šé‡"
+"æ–°è®¡ç®—ç†æƒ³è·¯å¾„。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "The radius of the agent."
-msgstr "圆柱体的åŠå¾„。"
+msgstr "代ç†çš„åŠå¾„。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -43010,6 +43384,8 @@ msgid ""
"will allow an agent to not have to hit a point on the path exactly, but in "
"the area."
msgstr ""
+"认为到达目标的è·ç¦»é˜ˆå€¼ã€‚å¯ä»¥è®©ä»£ç†æ— éœ€ç²¾å‡†åˆ°è¾¾è·¯å¾„上的æŸä¸ªç‚¹ï¼Œåˆ°è¾¾æŸä¸ªåŒºåŸŸå³"
+"å¯ã€‚"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
@@ -43019,33 +43395,36 @@ msgid ""
"other agents, but the less freedom in choosing its velocities. Must be "
"positive."
msgstr ""
+"考虑其他代ç†çš„å‰æä¸‹ï¼Œè¯¥ä»£ç†çš„速度的最短安全时间,这个速度是由防撞算法计算而"
+"æ¥çš„。这个数越大,该代ç†å“应其他代ç†çš„速度越快,但选择速度的自由度也越å°ã€‚å¿…"
+"须为正数。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid "Notifies when the final location is reached."
-msgstr "å½“åŠ¨ç”»æ’­æ”¾ç»“æŸæ—¶é€šçŸ¥ã€‚"
+msgstr "抵达终点ä½ç½®æ—¶å‘出通知。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Notifies when the navigation path changes. This can be triggered by the "
"navigation system or by the user changing the path."
msgstr ""
+"å¯¼èˆªè·¯å¾„æ”¹å˜æ—¶å‘出通知。å¯ä»¥ç”±å¯¼èˆªç³»ç»Ÿè§¦å‘,也å¯ä»¥ç”±ç”¨æˆ·å¯¹è·¯å¾„的修改触å‘。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Notifies when the player-defined target, set with [method "
"set_target_location], is reached."
-msgstr ""
+msgstr "抵达由 [method set_target_location] 设置的玩家定义目标时å‘出通知。"
#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Notifies when the collision avoidance velocity is calculated after a call to "
"[method set_velocity]."
-msgstr ""
+msgstr "调用 [method set_velocity] åŽï¼Œè®¡ç®—出防撞速度时å‘出通知。"
#: doc/classes/NavigationAgent2D.xml
msgid "2D agent used in navigation for collision avoidance."
-msgstr ""
+msgstr "在导航中用于防撞的 2D 代ç†ã€‚"
#: doc/classes/NavigationAgent2D.xml
msgid ""
@@ -43056,26 +43435,22 @@ msgid ""
"child of a [Navigation2D] node, or using [method set_navigation]. "
"[NavigationAgent2D] is physics safe."
msgstr ""
+"导航中使用的 2D 代ç†ï¼Œå¯ä»¥åœ¨å‰å¾€æŸä¸ªä½ç½®æ—¶èº²é¿é™æ€å’ŒåЍæ€éšœç¢ç‰©ã€‚躲é¿åЍæ€éšœç¢"
+"物使用的是 RVO(Reciprocal Velocity Obstacles,相对速度障ç¢ç‰©ï¼‰é˜²æ’žç®—法。代ç†"
+"需è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ­£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©ä»£ç†æˆä¸º [Navigation2D] 节点的å­é¡¹å®žçŽ°ï¼Œ"
+"也å¯ä»¥ä½¿ç”¨ [method set_navigation]。[NavigationAgent2D] 是物ç†å®‰å…¨çš„。"
#: doc/classes/NavigationAgent2D.xml
msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-#, fuzzy
-msgid ""
"Returns which index the agent is currently on in the navigation path's "
"[PoolVector2Array]."
-msgstr "以[PoolVector2Array]的形å¼è¿”回缓存的点。"
+msgstr "返回该代ç†å½“å‰ä½äºŽå¯¼èˆªè·¯å¾„ [PoolVector2Array] 中的哪个索引ä½ç½®ã€‚"
#: doc/classes/NavigationAgent2D.xml
-#, fuzzy
msgid ""
"Returns the [Navigation2D] node that the agent is using for its navigation "
"system."
-msgstr "返回指定å称的动画节点。"
+msgstr "返回该代ç†çš„导航系统所使用的 [Navigation2D] 节点。"
#: doc/classes/NavigationAgent2D.xml
msgid ""
@@ -43083,19 +43458,16 @@ msgid ""
"that there are no static objects in the way. If the agent does not have a "
"navigation path, it will return the position of the agent's parent."
msgstr ""
+"返回å¯ä»¥ç§»åŠ¨è‡³çš„ [Vector2] 免局忠‡ï¼Œç¡®ä¿ä¸­é€”æ²¡æœ‰é™æ€ç‰©ä½“é˜»æŒ¡ã€‚å¦‚æžœä»£ç†æ²¡æœ‰å¯¼"
+"航路径,则会返回代ç†çˆ¶èŠ‚ç‚¹çš„åŽŸç‚¹ã€‚"
#: doc/classes/NavigationAgent2D.xml
msgid ""
"Sets the [Navigation2D] node used by the agent. Useful when you don't want "
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
+"è®¾ç½®ä»£ç†æ‰€ä½¿ç”¨çš„ [Navigation2D] 节点。å¯ä»¥åœ¨ä½ ä¸æƒ³è®©ä»£ç†ä½œä¸º [Navigation2D] "
+"节点的å­èŠ‚ç‚¹æ—¶ä½¿ç”¨ã€‚"
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
@@ -43395,23 +43767,21 @@ msgstr "表示[enum SourceGeometryMode]枚举的大å°ã€‚"
#: doc/classes/NavigationMeshGenerator.xml
msgid "This class is responsible for creating and clearing navigation meshes."
-msgstr ""
+msgstr "这个类负责导航网格的创建和清ç†ã€‚"
#: doc/classes/NavigationMeshGenerator.xml
msgid ""
"Bakes the navigation mesh. This will allow you to use pathfinding with the "
"navigation system."
-msgstr ""
+msgstr "烘焙导航网格。å¯ä»¥ç”¨äºŽå¯¼èˆªç³»ç»Ÿä¸­çš„寻路。"
#: doc/classes/NavigationMeshGenerator.xml
-#, fuzzy
msgid "Clears the navigation mesh."
-msgstr "设置此项的导航网格。"
+msgstr "清除导航网格。"
#: doc/classes/NavigationMeshInstance.xml
-#, fuzzy
msgid "An instance of a [NavigationMesh]."
-msgstr "实例化 [MultiMesh] 的节点。"
+msgstr "[NavigationMesh] 的一个实例。"
#: doc/classes/NavigationMeshInstance.xml
msgid ""
@@ -43419,6 +43789,8 @@ msgid ""
"be navigated and what cannot, based on the [NavigationMesh] resource. This "
"should be a child of a [Navigation] node."
msgstr ""
+"[NavigationMesh] çš„ä¸€ä¸ªå®žä¾‹ã€‚å®ƒä¼šæ ¹æ® [NavigationMesh] 资æºï¼Œå‘ŠçŸ¥ "
+"[Navigation] 节点什么å¯ä»¥å¯¼èˆªã€ä»€ä¹ˆä¸å¯ä»¥ã€‚应该是 [Navigation] 节点的å­èŠ‚ç‚¹ã€‚"
#: doc/classes/NavigationMeshInstance.xml
msgid ""
@@ -43426,30 +43798,28 @@ msgid ""
"navigation baking is not a cheap operation. This can be done at runtime. "
"When it is completed, it automatically sets the new [NavigationMesh]."
msgstr ""
+"烘焙 [NavigationMesh]。烘焙是在å•ç‹¬çš„çº¿ç¨‹ä¸­è¿›è¡Œçš„ï¼Œå› ä¸ºå¯¼èˆªçš„çƒ˜ç„™å¹¶ä¸æ˜¯å»‰ä»·æ“"
+"作。å¯ä»¥åœ¨è¿è¡Œæ—¶è¿›è¡Œã€‚完æˆåŽï¼Œä¼šè‡ªåŠ¨è®¾ç½®æ–°çš„ [NavigationMesh]。"
#: doc/classes/NavigationMeshInstance.xml
-#, fuzzy
msgid "Determines if the [NavigationMeshInstance] is enabled or disabled."
-msgstr "递归扫æ [NavigationMeshInstance] çš„å­èŠ‚ç‚¹ä»¥èŽ·å–几何体。"
+msgstr "决定该 [NavigationMeshInstance] å·²å¯ç”¨è¿˜æ˜¯å·²ç¦ç”¨ã€‚"
#: doc/classes/NavigationMeshInstance.xml
-#, fuzzy
msgid "The [NavigationMesh] resource to use."
-msgstr "实例的 [NavigationMesh] 资æºã€‚"
+msgstr "使用的 [NavigationMesh] 资æºã€‚"
#: doc/classes/NavigationMeshInstance.xml
-#, fuzzy
msgid "Notifies when the navigation mesh bake operation is completed."
-msgstr "当动画开始播放时通知。"
+msgstr "导航网格烘焙æ“ä½œå®Œæˆæ—¶å‘出通知。"
#: doc/classes/NavigationMeshInstance.xml
-#, fuzzy
msgid "Notifies when the [NavigationMesh] has changed."
-msgstr "当动画开始播放时通知。"
+msgstr "[NavigationMesh] å‘生å˜åŒ–æ—¶å‘出通知。"
#: doc/classes/NavigationObstacle.xml
msgid "3D obstacle used in navigation for collision avoidance."
-msgstr ""
+msgstr "在导航中用于防撞的 3D éšœç¢ç‰©ã€‚"
#: doc/classes/NavigationObstacle.xml
msgid ""
@@ -43458,58 +43828,66 @@ msgid ""
"as a child of a [Navigation] node, or using [method set_navigation]. "
"[NavigationObstacle] is physics safe."
msgstr ""
+"导航中用于防撞的 3D éšœç¢ç‰©ã€‚éšœç¢ç‰©éœ€è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ­£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©éšœç¢ç‰©"
+"æˆä¸º [Navigation] 节点的å­é¡¹å®žçŽ°ï¼Œä¹Ÿå¯ä»¥ä½¿ç”¨ [method set_navigation]。"
+"[NavigationObstacle] 是物ç†å®‰å…¨çš„。"
#: doc/classes/NavigationObstacle.xml
-#, fuzzy
msgid ""
"Returns the [Navigation] node that the obstacle is using for its navigation "
"system."
-msgstr "返回指定å称的动画节点。"
+msgstr "返回该障ç¢ç‰©çš„导航系统所使用的 [Navigation] 节点。"
#: doc/classes/NavigationObstacle.xml
msgid ""
"Sets the [Navigation] node used by the obstacle. Useful when you don't want "
"to make the obstacle a child of a [Navigation] node."
msgstr ""
+"设置障ç¢ç‰©æ‰€ä½¿ç”¨çš„ [Navigation] 节点。å¯ä»¥åœ¨ä½ ä¸æƒ³è®©éšœç¢ç‰©ä½œä¸º [Navigation] "
+"节点的å­èŠ‚ç‚¹æ—¶ä½¿ç”¨ã€‚"
#: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml
msgid ""
"Enables radius estimation algorithm which uses parent's collision shapes to "
"determine the obstacle radius."
-msgstr ""
+msgstr "å¯ç”¨åŠå¾„估算算法,使用父项的碰撞形状确定障ç¢ç‰©çš„åŠå¾„。"
#: doc/classes/NavigationObstacle.xml doc/classes/NavigationObstacle2D.xml
-#, fuzzy
msgid ""
"The radius of the agent. Used only if [member estimate_radius] is set to "
"[code]false[/code]."
msgstr ""
-"è®¾ç½®ä¸»æŒ‰é’®çš„åˆ‡æ¢æ¨¡å¼çжæ€ã€‚åªæœ‰å½“ [member toggle_mode] 被设置为 [code]true[/"
-"code] æ—¶æ‰èµ·ä½œç”¨ã€‚"
+"代ç†çš„åŠå¾„。仅在 [member estimate_radius] 为 [code]false[/code] 时使用。"
#: doc/classes/NavigationObstacle2D.xml
msgid "2D obstacle used in navigation for collision avoidance."
-msgstr ""
+msgstr "在导航中用于防撞的 2D éšœç¢ç‰©ã€‚"
#: doc/classes/NavigationObstacle2D.xml
+#, fuzzy
msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
+"导航中用于防撞的 2D éšœç¢ç‰©ã€‚éšœç¢ç‰©éœ€è¦å¯¼èˆªæ•°æ®æ‰èƒ½æ­£ç¡®å·¥ä½œã€‚å¯ä»¥é€šè¿‡è®©éšœç¢ç‰©"
+"æˆä¸º [Navigation2D] 节点的å­é¡¹å®žçŽ°ï¼Œä¹Ÿå¯ä»¥ä½¿ç”¨ [method set_navigation]。"
+"[NavigationObstacle] 是物ç†å®‰å…¨çš„。"
#: doc/classes/NavigationObstacle2D.xml
msgid ""
"Returns the [Navigation2D] node that the obstacle is using for its "
"navigation system."
-msgstr ""
+msgstr "返回该障ç¢ç‰©çš„导航系统所使用的 [Navigation2D] 节点。"
#: doc/classes/NavigationObstacle2D.xml
msgid ""
"Sets the [Navigation2D] node used by the obstacle. Useful when you don't "
"want to make the obstacle a child of a [Navigation2D] node."
msgstr ""
+"设置障ç¢ç‰©æ‰€ä½¿ç”¨çš„ [Navigation2D] 节点。å¯ä»¥åœ¨ä½ ä¸æƒ³è®©éšœç¢ç‰©ä½œä¸º "
+"[Navigation2D] 节点的å­èŠ‚ç‚¹æ—¶ä½¿ç”¨ã€‚"
#: doc/classes/NavigationPolygon.xml
msgid ""
@@ -43638,9 +44016,8 @@ msgstr ""
"make_polygons_from_outlines] æ¥æ›´æ–°å¤šè¾¹å½¢ã€‚"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Server interface for low-level 3D navigation access."
-msgstr "低级音频访问的æœåŠ¡å™¨æŽ¥å£ã€‚"
+msgstr "访问底层 3D 导航的æœåŠ¡å™¨æŽ¥å£ã€‚"
#: doc/classes/NavigationServer.xml
msgid ""
@@ -43663,34 +44040,43 @@ msgid ""
"phase. This means that you can request any change to the map, using any "
"thread, without worrying."
msgstr ""
+"NavigationServer 是负责所有 3D 导航的æœåŠ¡å™¨ï¼Œå¤„ç†çš„对象有地图(map)ã€åœ°åŒº"
+"(region)ã€ä»£ç†ï¼ˆagent)。\n"
+"地图是由地区组æˆçš„,地区åˆç”±å¯¼èˆªç½‘格组æˆã€‚å®ƒä»¬ä¸€åŒæž„æˆäº† 3D 世界中的å¯å¯¼èˆªåŒº"
+"域。两个地区必须共有一æ¡ç›¸ä¼¼çš„边界(edge)æ‰èƒ½ç›¸è¿žã€‚如果一æ¡è¾¹ç•Œçš„两个顶点"
+"(vertex)与å¦ä¸€æ¡è¾¹ç•Œçš„对应顶点的è·ç¦»å°äºŽ [member Navigation."
+"edge_connection_margin],则认为这两æ¡è¾¹ç•Œç›¸è¿žã€‚\n"
+"è¦ä½¿ç”¨é˜²æ’žç³»ç»Ÿï¼Œå¯ä»¥ä½¿ç”¨ä»£ç†ã€‚ä½ å¯ä»¥è®¾ç½®ä»£ç†çš„目标速度,æœåŠ¡å™¨å°±ä¼šä½¿ç”¨ä¿®æ­£åŽ"
+"的速度触å‘回调。\n"
+"[b]注æ„:[/b]防撞系统会忽略地区。直接使用修正åŽçš„速度å¯èƒ½ä¼šå°†ä»£ç†æŽ¨åˆ°å¯å¯¼èˆªåŒº"
+"åŸŸä¹‹å¤–ã€‚è¿™æ˜¯é˜²æ’žç³»ç»Ÿçš„ç¼ºé™·ï¼Œæ›´å¤æ‚的情况å¯èƒ½éœ€è¦ç”¨åˆ°ç‰©ç†å¼•擎。\n"
+"æœåŠ¡å™¨ä¼šè®°å½•æ‰€æœ‰çš„è°ƒç”¨ï¼Œåœ¨åŒæ­¥é˜¶æ®µç»Ÿä¸€æ‰§è¡Œã€‚è¿™æ„味ç€ä½ å¯ä»¥æ”¾å¿ƒå¤§èƒ†åœ°ä»Žä»»ä½•线"
+"程中请求对地图进行任何修改。"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid ""
"Returns the normal for the point returned by [method map_get_closest_point]."
-msgstr "返回碰撞点相交物体形状的法线。"
+msgstr "返回 [method map_get_closest_point] 所返回的点的法线。"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid ""
"Returns the closest point between the navigation surface and the segment."
-msgstr "起点和终点之间点的样å¼ã€‚"
+msgstr "返回导航表é¢ä¸Žè¯¥çº¿æ®µä¹‹é—´æœ€æŽ¥è¿‘的点。"
#: doc/classes/NavigationServer.xml
msgid ""
"Returns the edge connection margin of the map. This distance is the minimum "
"vertex distance needed to connect two edges from different regions."
msgstr ""
+"返回地图的边界连接边è·ã€‚这是让两个ä¸åŒåœ°åŒºçš„边界相连所需的最å°é¡¶ç‚¹è·ç¦»ã€‚"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Returns the map's up direction."
-msgstr "返回ä½å›¾çš„尺寸。"
+msgstr "返回地图的上方å‘。"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Sets the map up direction."
-msgstr "åœæ­¢éŸ³é¢‘。"
+msgstr "设置地图的上方å‘。"
#: doc/classes/NavigationServer.xml
msgid ""
@@ -43699,16 +44085,17 @@ msgid ""
"called in the main thread.\n"
"[b]Note:[/b] This function is not thread safe."
msgstr ""
+"处ç†é˜²æ’žä»£ç†ã€‚\n"
+"ç‰©ç†æœåŠ¡å™¨éœ€è¦è¿™ä¸ªå¤„ç†çš„结果,所以必须在主线程中调用。\n"
+"[b]注æ„:[/b]è¿™ä¸ªå‡½æ•°ä¸æ˜¯çº¿ç¨‹å®‰å…¨çš„。"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Bakes the navigation mesh."
-msgstr "设置此项的导航网格。"
+msgstr "烘焙导航网格。"
#: doc/classes/NavigationServer.xml
-#, fuzzy
msgid "Control activation of this server."
-msgstr "æ­¤èŠ‚ç‚¹çš„å±€éƒ¨å˜æ¢ã€‚"
+msgstr "控制这个æœåŠ¡å™¨æ˜¯å¦æ¿€æ´»ã€‚"
#: modules/enet/doc_classes/NetworkedMultiplayerENet.xml
msgid ""
@@ -47648,6 +48035,7 @@ msgstr ""
"在文件的末尾是所有已使用资æºç±»åž‹çš„统计数æ®ã€‚"
#: doc/classes/OS.xml
+#, fuzzy
msgid ""
"Execute the file at the given path with the arguments passed as an array of "
"strings. Platform path resolution will take place. The resolved file must "
@@ -47666,6 +48054,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -48185,18 +48576,17 @@ msgstr ""
msgid ""
"Returns the amount of time in milliseconds it took for the boot logo to "
"appear."
-msgstr "返回å¯åŠ¨æ ‡å¿—å‡ºçŽ°æ‰€èŠ±è´¹çš„æ—¶é—´(以毫秒为å•ä½)。"
+msgstr "返回å¯åŠ¨å¾½æ ‡å‡ºçŽ°æ‰€èŠ±è´¹çš„æ—¶é—´ï¼Œå•ä½ä¸ºæ¯«ç§’。"
#: doc/classes/OS.xml
msgid "Returns the maximum amount of static memory used (only works in debug)."
-msgstr "è¿”å›žä½¿ç”¨çš„é™æ€å†…存的最大数é‡(仅在调试中有效)。"
+msgstr "è¿”å›žä½¿ç”¨çš„é™æ€å†…存的最大数é‡ï¼ˆä»…在调试时有效)。"
#: doc/classes/OS.xml
-#, fuzzy
msgid ""
"Returns the amount of static memory being used by the program in bytes (only "
"works in debug)."
-msgstr "è¿”å›žç¨‹åºæ‰€ä½¿ç”¨çš„陿€å†…å­˜é‡ï¼Œä»¥å­—节为å•ä½ã€‚"
+msgstr "è¿”å›žç¨‹åºæ‰€ä½¿ç”¨çš„陿€å†…å­˜é‡ï¼Œä»¥å­—节为å•ä½ï¼ˆä»…在调试时有效)。"
#: doc/classes/OS.xml
msgid ""
@@ -49970,6 +50360,7 @@ msgid "GPU-based 3D particle emitter."
msgstr "基于GPUçš„3Dç²’å­å‘射器。"
#: doc/classes/Particles.xml
+#, fuzzy
msgid ""
"3D particle node used to create a variety of particle systems and effects. "
"[Particles] features an emitter that generates some number of particles at a "
@@ -49982,6 +50373,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -50110,6 +50505,7 @@ msgid "GPU-based 2D particle emitter."
msgstr "基于GPUçš„2Dç²’å­å‘射器。"
#: doc/classes/Particles2D.xml
+#, fuzzy
msgid ""
"2D particle node used to create a variety of particle systems and effects. "
"[Particles2D] features an emitter that generates some number of particles at "
@@ -50122,6 +50518,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -50728,13 +51128,13 @@ msgid ""
"points and increase memory consumption, or make a cubic interpolation "
"between two points at the cost of (slightly) slower calculations."
msgstr ""
-"如果[code]为true[/code],则两个缓存点之间的ä½ç½®å°†è¿›è¡Œä¸‰æ¬¡æ’值,å¦åˆ™å°†çº¿æ€§æ’"
+"如果为 [code]true[/code],则两个缓存点之间的ä½ç½®å°†è¿›è¡Œä¸‰æ¬¡æ’值,å¦åˆ™å°†çº¿æ€§æ’"
"值。\n"
-"沿ç€[Path2D]çš„[Curve2D]的点在使用å‰è¢«é¢„先计算,以更快的计算速度。然åŽåœ¨ä¸¤ä¸ªç›¸"
-"邻的缓存点之间计算请求åç§»é‡çš„点。这å¯èƒ½ä¼šå‡ºçŽ°ä¸€ä¸ªé—®é¢˜ï¼Œå¦‚æžœæ›²çº¿åšæ€¥è½¬å¼¯ï¼Œå› "
-"为缓存点å¯èƒ½ä¸è·Ÿéšæ›²çº¿è¶³å¤Ÿè¿‘ã€‚\n"
-"æœ‰ä¸¤ç§æ–¹æ³•å¯ä»¥è§£å†³è¿™ä¸ªé—®é¢˜:è¦ä¹ˆå¢žåŠ ç¼“å­˜ç‚¹çš„æ•°é‡ï¼Œå¢žåŠ å†…å­˜æ¶ˆè€—ï¼Œè¦ä¹ˆåœ¨ä¸¤ä¸ªç‚¹ä¹‹"
-"间进行三次æ’值,但代价是(ç¨å¾®)é™ä½Žè®¡ç®—速度。"
+"æ²¿ç€ [Path2D] çš„ [Curve2D] 的点在使用å‰è¢«é¢„先计算,以更快的计算速度。然åŽåœ¨ä¸¤"
+"个相邻的缓存点之间计算请求åç§»é‡çš„点。这å¯èƒ½ä¼šå‡ºçŽ°ä¸€ä¸ªé—®é¢˜ï¼Œå¦‚æžœæ›²çº¿åšæ€¥è½¬"
+"弯,因为缓存点å¯èƒ½ä¸è·Ÿéšæ›²çº¿è¶³å¤Ÿè¿‘ã€‚\n"
+"æœ‰ä¸¤ç§æ–¹æ³•å¯ä»¥è§£å†³è¿™ä¸ªé—®é¢˜ï¼šè¦ä¹ˆå¢žåŠ ç¼“å­˜ç‚¹çš„æ•°é‡ï¼Œå¢žåŠ å†…å­˜æ¶ˆè€—ï¼Œè¦ä¹ˆåœ¨ä¸¤ä¸ªç‚¹"
+"之间进行三次æ’值,但代价是(ç¨å¾®ï¼‰é™ä½Žè®¡ç®—速度。"
#: doc/classes/PathFollow2D.xml
msgid ""
@@ -50752,7 +51152,7 @@ msgstr "沿ç€è·¯å¾„çš„è·ç¦»ï¼Œå•ä½ä¸ºåƒç´ ã€‚"
msgid ""
"If [code]true[/code], this node rotates to follow the path, making its "
"descendants rotate."
-msgstr "如果[code]为true[/code],则该节点将沿ç€è·¯å¾„旋转,使其åŽä»£èŠ‚ç‚¹æ—‹è½¬ã€‚"
+msgstr "如果为 [code]true[/code],则该节点将沿ç€è·¯å¾„旋转,使其åŽä»£èŠ‚ç‚¹æ—‹è½¬ã€‚"
#: doc/classes/PathFollow2D.xml
msgid ""
@@ -52284,11 +52684,11 @@ msgstr "å½“å¯¹è±¡é€€å‡ºå…¶å½¢çŠ¶ä¹‹ä¸€æ—¶ï¼Œç¬¬ä¸€ä¸ªå‚æ•°å’ŒåŒºåŸŸå›žè°ƒå‡½æ•°
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant to get the number of objects that are not sleeping."
-msgstr "常é‡ï¼Œç”¨æ¥èŽ·å–æœªå¤„于ç¡çœ çжæ€çš„对象的数é‡ã€‚"
+msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–æœªå¤„于ç¡çœ çжæ€çš„对象的数é‡ã€‚"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid "Constant to get the number of possible collisions."
-msgstr "常数,用以获å–å¯èƒ½çš„碰撞数。"
+msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–å¯èƒ½çš„碰撞数。"
#: doc/classes/Physics2DServer.xml doc/classes/PhysicsServer.xml
msgid ""
@@ -52297,7 +52697,7 @@ msgstr "常é‡ï¼Œç”¨ä»¥èŽ·å–å¯èƒ½å‘生碰撞的空间区域数。"
#: doc/classes/Physics2DShapeQueryParameters.xml
msgid "Parameters to be sent to a 2D shape physics query."
-msgstr "è¦å‘é€åˆ°2Då½¢çŠ¶ç‰©ç†æŸ¥è¯¢çš„傿•°ã€‚"
+msgstr "è¦å‘é€åˆ° 2D å½¢çŠ¶ç‰©ç†æŸ¥è¯¢çš„傿•°ã€‚"
#: doc/classes/Physics2DShapeQueryParameters.xml
msgid ""
@@ -52403,7 +52803,7 @@ msgstr "碰撞层和碰撞掩ç ã€‚访问时返回碰撞层。修改时更新碰
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Direct access object to a physics body in the [PhysicsServer]."
-msgstr "直接访问[PhysicsServer]中的物ç†ä½“的对象。"
+msgstr "直接访问 [PhysicsServer] 中的物ç†ä½“的对象。"
#: doc/classes/PhysicsDirectBodyState.xml
msgid ""
@@ -52454,8 +52854,8 @@ msgid ""
"This will rotate the body around the vector [code]j[/code] passed as "
"parameter."
msgstr ""
-"施加一个扭矩冲é‡(这将å—到物体质é‡å’Œå½¢çŠ¶çš„å½±å“)ã€‚è¿™å°†å›´ç»•ä½œä¸ºå‚æ•°ä¼ é€’çš„å‘é‡"
-"[code]j[/code]旋转主体。"
+"施加一个扭矩冲é‡ï¼ˆå°†å—到物体质é‡å’Œå½¢çŠ¶çš„å½±å“ï¼‰ã€‚è¿™å°†å›´ç»•ä½œä¸ºå‚æ•°ä¼ é€’çš„å‘é‡ "
+"[code]j[/code] 旋转主体。"
#: doc/classes/PhysicsDirectBodyState.xml
msgid "Returns the collider object."
@@ -52488,15 +52888,15 @@ msgstr "物体的线速度,å•ä½ä¸ºå•使¯ç§’。"
#: doc/classes/PhysicsDirectSpaceState.xml
msgid "Direct access object to a space in the [PhysicsServer]."
-msgstr "直接访问[PhysicsServer]中空间的对象。"
+msgstr "直接访问 [PhysicsServer] 中空间的对象。"
#: doc/classes/PhysicsDirectSpaceState.xml
msgid ""
"Direct access object to a space in the [PhysicsServer]. It's used mainly to "
"do queries against objects and areas residing in a given space."
msgstr ""
-"直接访问[PhysicsServer]中空间的对象。它主è¦ç”¨äºŽå¯¹é©»ç•™åœ¨ç‰¹å®šç©ºé—´çš„对象和区域进"
-"行查询。"
+"直接访问 [PhysicsServer] 中空间的对象。它主è¦ç”¨äºŽå¯¹é©»ç•™åœ¨ç‰¹å®šç©ºé—´çš„对象和区域"
+"进行查询。"
#: doc/classes/PhysicsDirectSpaceState.xml
msgid ""
@@ -53028,7 +53428,7 @@ msgstr "铰链上的最大旋转。"
#: doc/classes/PhysicsServer.xml
msgid "The minimum rotation across the Hinge."
-msgstr "ç©¿è¿‡é“°é“¾çš„æœ€å°æ—‹è½¬ã€‚"
+msgstr "é“°é“¾ä¸Šçš„æœ€å°æ—‹è½¬ã€‚"
#: doc/classes/PhysicsServer.xml
msgid "If [code]true[/code], the Hinge has a maximum and a minimum rotation."
@@ -53042,13 +53442,13 @@ msgstr "如果[code]true[/code],电机将转动铰链。"
msgid ""
"The maximum difference between the pivot points on their X axis before "
"damping happens."
-msgstr "阻尼å‘生å‰X轴上枢轴点之间的最大差异。"
+msgstr "阻尼å‘生å‰è½´å¿ƒç‚¹ä¹‹é—´åœ¨ X 轴上的最大差异。"
#: doc/classes/PhysicsServer.xml doc/classes/SliderJoint.xml
msgid ""
"The minimum difference between the pivot points on their X axis before "
"damping happens."
-msgstr "阻尼å‘生å‰X轴上枢轴点之间的最å°å·®å¼‚。"
+msgstr "阻尼å‘生å‰è½´å¿ƒç‚¹ä¹‹é—´åœ¨ X 轴上的最å°å·®å¼‚。"
#: doc/classes/PhysicsServer.xml doc/classes/SliderJoint.xml
msgid ""
@@ -53740,7 +54140,6 @@ msgstr ""
"大å°ã€‚使用 [enum File.CompressionMode] 常é‡ä¹‹ä¸€è®¾ç½®åŽ‹ç¼©æ¨¡å¼ã€‚"
#: doc/classes/PoolByteArray.xml
-#, fuzzy
msgid ""
"Returns a new [PoolByteArray] with the data decompressed. Set the "
"compression mode using one of [enum File.CompressionMode]'s constants. "
@@ -53757,15 +54156,15 @@ msgid ""
"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."
msgstr ""
-"返回数æ®è§£åŽ‹åŽçš„æ–° [PoolByteArray] 。使用 [enum File.CompressionMode] 的常数"
-"之一设置压缩模å¼ã€‚[b]æ­¤æ–¹æ³•ä»…æŽ¥å— gzip å’Œdeflate压缩模å¼ã€‚[/b]\n"
-"此方法å¯èƒ½æ¯” [code]decompress[/code] 慢,因为它å¯èƒ½éœ€è¦åœ¨è§£åŽ‹æ—¶å¤šæ¬¡é‡æ–°åˆ†é…å…¶"
-"输出缓冲器,因为 [code]decompress[/code] 从一开始就知é“它的输出缓冲器大å°ã€‚\n"
+"返回包å«è§£åŽ‹åŽæ•°æ®çš„æ–° [PoolByteArray]。请使用 [enum File.CompressionMode] 常"
+"é‡ä¹‹ä¸€è®¾ç½®åŽ‹ç¼©æ¨¡å¼ã€‚[b]è¿™ä¸ªæ–¹æ³•åªæŽ¥å— gzip å’Œ deflate 压缩模å¼ã€‚[/b]\n"
+"这个方法å¯èƒ½æ¯” [code]decompress[/code] 慢,因为在解压时å¯èƒ½éœ€è¦å¤šæ¬¡é‡æ–°åˆ†é…输"
+"出缓冲区,而 [code]decompress[/code] 则在一开始就知é“输出缓冲区的大å°ã€‚\n"
"\n"
-"GZIP 的最大压缩比为 1032:1,这æ„味ç€å°åž‹åŽ‹ç¼©æœ‰æ•ˆè½½è·æžæœ‰å¯èƒ½å‡åŽ‹åˆ°æ½œåœ¨çš„éžå¸¸"
-"å¤§è¾“å‡ºã€‚ä¸ºäº†é˜²æ­¢è¿™ç§æƒ…况,您å¯ä»¥æä¾›æœ€å¤§å°ºå¯¸ï¼Œå…许此函数通过 "
-"[code]max_output_size[/code] 以字节进行分é…。通过 -1 å°†å…许无é™åˆ¶è¾“出。如果通"
-"过任何正值,并且解压超过给定的字节值,则将返回错误。"
+"GZIP 的最大压缩率为 1032:1,这æ„味ç€è¾ƒå°çš„压缩åŽè´Ÿè½½å¾ˆæœ‰å¯èƒ½è§£åŽ‹å‡ºéžå¸¸å·¨å¤§çš„"
+"è¾“å‡ºã€‚ä¸ºäº†é˜²æ­¢è¿™ç§æƒ…况,你å¯ä»¥é€šè¿‡ [code]max_output_size[/code] æä¾›å…许这个"
+"函数分é…的最大字节数。传入 -1 则ä¸é™åˆ¶è¾“出。传入正数且解压超过该字节数时,会"
+"返回错误。"
#: doc/classes/PoolByteArray.xml
msgid ""
@@ -55431,12 +55830,15 @@ msgid ""
msgstr "设置é…置值的顺åºï¼ˆä¿å­˜åˆ°é…置文件时会产生影å“)。"
#: doc/classes/ProjectSettings.xml
+#, fuzzy
msgid ""
"Sets the value of a setting.\n"
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
"设置给定é…置项的值。\n"
"[b]示例:[/b]\n"
@@ -55887,21 +56289,22 @@ msgid ""
"projects (Godot 2), as using member variables is the preferred style from "
"Godot 3 onwards."
msgstr ""
-"如果[code]true[/code],则在脚本编辑器的自动完æˆç»“果中显示getterså’Œsetters。这"
-"ä¸ªè®¾ç½®æ˜¯ä¸ºäº†åœ¨ç§»æ¤æ—§é¡¹ç›®(戈多2)时使用,因为使用æˆå‘˜å˜é‡æ˜¯ä»Žæˆˆå¤š3开始的首选风"
-"格。"
+"如果为 [code]true[/code],则在脚本编辑器的自动完æˆç»“果中显示 Getter å’Œ "
+"Setterã€‚è¿™ä¸ªè®¾ç½®æ˜¯ä¸ºäº†åœ¨ç§»æ¤æ—§é¡¹ç›®ï¼ˆGodot 2)时使用,因为使用æˆå‘˜å˜é‡æ˜¯ä»Ž "
+"Godot 3 开始的首选风格。"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when a constant is used as a function."
-msgstr "如果[code]true[/code],则当常é‡ç”¨ä½œå‡½æ•°æ—¶ä¼šå‘出警告。"
+msgstr "如果为 [code]true[/code],则当常é‡ç”¨ä½œå‡½æ•°æ—¶ä¼šå‘出警告。"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], enables warnings when deprecated keywords such as "
"[code]slave[/code] are used."
msgstr ""
-"如果[code]true[/code],当使用已废弃的关键字如[code]slave[/code]时,å¯ç”¨è­¦å‘Šã€‚"
+"如果为 [code]true[/code],当使用已废弃的 [code]slave[/code] 等关键字时,将å¯"
+"用警告。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -55909,16 +56312,17 @@ msgid ""
"gdscript/warnings/*[/code] settings). If [code]false[/code], disables all "
"GDScript warnings."
msgstr ""
-"如果[code]true[/code],则å¯ç”¨ç‰¹å®šçš„GDScript警告(请å‚阅[code]debug/gdscript/"
-"warnings/*[/code]设置)。如果[code]为false[/code],则ç¦ç”¨æ‰€æœ‰GDScript警告。"
+"如果为 [code]true[/code],则å¯ç”¨ç‰¹å®šçš„ GDScript 警告(请å‚阅 [code]debug/"
+"gdscript/warnings/*[/code] 设置)。如果为 [code]false[/code],则ç¦ç”¨æ‰€æœ‰ "
+"GDScript 警告。"
#: doc/classes/ProjectSettings.xml
msgid ""
"If [code]true[/code], scripts in the [code]res://addons[/code] folder will "
"not generate warnings."
msgstr ""
-"如果[code]true[/code],则[code]res://addons[/code]文件夹中的脚本ä¸ä¼šç”Ÿæˆè­¦"
-"告。"
+"如果为 [code]true[/code],则 [code]res://addons[/code] 文件夹中的脚本ä¸ä¼šç”Ÿæˆ"
+"警告。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -55940,7 +56344,7 @@ msgid ""
"If [code]true[/code], enables warnings when a function assigned to a "
"variable may yield and return a function state instead of a value."
msgstr ""
-"如果[code]为true[/code],则当分é…ç»™å˜é‡çš„函数å¯èƒ½äº§ç”Ÿå¹¶è¿”回函数状æ€è€Œä¸æ˜¯å€¼"
+"如果为 [code]true[/code],则当分é…ç»™å˜é‡çš„函数å¯èƒ½äº§ç”Ÿå¹¶è¿”回函数状æ€è€Œä¸æ˜¯å€¼"
"时,å¯ç”¨è­¦å‘Šã€‚"
#: doc/classes/ProjectSettings.xml
@@ -55961,8 +56365,8 @@ msgid ""
"If [code]true[/code], enables warnings when dividing an integer by another "
"integer (the decimal part will be discarded)."
msgstr ""
-"如果[code]为true[/code],则在用一个整数除以å¦ä¸€ä¸ªæ•´æ•°æ—¶å¯ç”¨è­¦å‘Š(å°æ•°éƒ¨åˆ†å°†è¢«"
-"丢弃)。"
+"如果为 [code]true[/code],则在用一个整数除以å¦ä¸€ä¸ªæ•´æ•°æ—¶å¯ç”¨è­¦å‘Šï¼ˆå°æ•°éƒ¨åˆ†å°†"
+"被丢弃)。"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -55970,7 +56374,7 @@ msgid ""
"to a function that expects an integer (it will be converted and lose "
"precision)."
msgstr ""
-"如果 [code]为true[/code]ï¼Œåˆ™åœ¨å°†æµ®ç‚¹å€¼ä¼ é€’ç»™éœ€è¦æ•´æ•°çš„函数时å¯ç”¨è­¦å‘Šï¼ˆå®ƒå°†è¢«"
+"如果为 [code]true[/code]ï¼Œåˆ™åœ¨å°†æµ®ç‚¹å€¼ä¼ é€’ç»™éœ€è¦æ•´æ•°çš„函数时å¯ç”¨è­¦å‘Šï¼ˆå®ƒå°†è¢«"
"转æ¢å¹¶å¤±åŽ»ç²¾åº¦ï¼‰ã€‚"
#: doc/classes/ProjectSettings.xml
@@ -56427,6 +56831,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -57746,11 +58162,11 @@ msgid ""
"NVIDIA GPUs at the cost of performance. This option affects GLES2 and GLES3 "
"rendering, but only on desktop platforms."
msgstr ""
-"一些NVIDIA GPU驱动有bug,对[code]draw_rect[/code]方法产生闪çƒé—®é¢˜ï¼Œç‰¹åˆ«æ˜¯åœ¨"
-"[TileMap]中使用时。详情å‚阅[url=https://github.com/godotengine/godot/"
+"一些 NVIDIA GPU 驱动有 bug,对 [code]draw_rect[/code] 方法产生闪çƒé—®é¢˜ï¼Œç‰¹åˆ«"
+"是在 [TileMap] 中使用时。详情å‚阅 [url=https://github.com/godotengine/godot/"
"issues/9913]GitHub issue 9913[/url]。\n"
-"如果[code]为true[/code],该选项将为此类NVIDIA GPUå¯ç”¨ \"安全\" 的代ç è·¯å¾„,但"
-"会牺牲性能。这个选项会影å“GLES2å’ŒGLES3的渲染,但åªåœ¨æ¡Œé¢å¹³å°ä¸Šã€‚"
+"如果为 [code]true[/code],该选项将为此类 NVIDIA GPU å¯ç”¨â€œå®‰å…¨â€çš„代ç è·¯å¾„,但"
+"ä¼šç‰ºç‰²æ€§èƒ½ã€‚è¿™ä¸ªé€‰é¡¹ä¼šå½±å“ GLES2 å’Œ GLES3 的渲染,但åªåœ¨æ¡Œé¢å¹³å°ä¸Šã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -58272,7 +58688,6 @@ msgstr ""
"相关的æ¯ä¸€å¸§ï¼Œä»¥æä¾›æœ€ä½³çš„æ•´ä½“性能。"
#: doc/classes/ProjectSettings.xml
-#, fuzzy
msgid ""
"The default convention is for portal normals to point outward (face outward) "
"from the source room.\n"
@@ -58281,10 +58696,10 @@ msgid ""
"It will flip named portal meshes (i.e. [code]-portal[/code]) on the initial "
"conversion to [Portal] nodes."
msgstr ""
-"默认的惯例是,portal的法线从æºç©ºé—´å‘外。\n"
-"å¦‚æžœä½ åœ¨å»ºé€ å…³å¡æ—¶ä¸å°å¿ƒå°†portalæœå‘了错误的方å‘,这个设置å¯ä»¥è§£å†³è¿™ä¸ªé—®"
+"默认的惯例是,入å£çš„æ³•çº¿æŒ‡å‘æºæˆ¿é—´å¤–éƒ¨ï¼ˆé¢æœå¤–)。\n"
+"å¦‚æžœä½ åœ¨å»ºé€ å…³å¡æ—¶ä¸å°å¿ƒå°†å…¥å£éƒ½æœå‘了错误的方å‘,这个设置å¯ä»¥è§£å†³è¿™ä¸ªé—®"
"题。\n"
-"它将在åˆå§‹è½¬æ¢ä¸º[Portal]节点时翻转命åçš„portal网格(å³[code]-portal[/"
+"它将在åˆå§‹è½¬æ¢ä¸º [Portal] 节点时翻转命å的入å£ç½‘æ ¼ï¼ˆå³ [code]-portal[/"
"code])。"
#: doc/classes/ProjectSettings.xml
@@ -58339,16 +58754,15 @@ msgstr ""
"时,æ‰åº”该使用该选项。"
#: doc/classes/ProjectSettings.xml
-#, fuzzy
msgid ""
"If [code]true[/code], allocates the root [Viewport]'s framebuffer with high "
"dynamic range. High dynamic range allows the use of [Color] values greater "
"than 1.\n"
"[b]Note:[/b] Only available on the GLES3 backend."
msgstr ""
-"如果 [code]true[/code],则分é…具有高动æ€èŒƒå›´ï¼ˆHDR)的主帧缓冲区。高动æ€èŒƒå›´å…"
-"许使用大于 1 的 [Color] 值。\n"
-"[b]注æ„:[/b] 仅在 GLES3 åŽç«¯å¯ç”¨ã€‚"
+"如果为 [code]true[/code]ï¼Œåˆ†é…æ ¹ [Viewport] 的帧缓冲时将使用高动æ€èŒƒå›´ã€‚高动"
+"æ€èŒƒå›´å…许使用大于 1 çš„ [Color] 值。\n"
+"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸­å¯ç”¨ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -58370,6 +58784,13 @@ msgid ""
"enable [member rendering/quality/filters/use_debanding] instead.\n"
"[b]Note:[/b] Only available on the GLES3 backend."
msgstr ""
+"如果为 [code]true[/code]ï¼Œåˆ†é…æ ¹ [Viewport] 的帧缓冲时将使用完整浮点数精度"
+"(32 ä½ï¼‰è€Œä¸æ˜¯åŠæµ®ç‚¹æ•°ç²¾åº¦ï¼ˆ16 ä½ï¼‰ã€‚ä»…åœ¨åŒæ—¶å¯ç”¨ [member rendering/quality/"
+"depth/hdr] 时有效。\n"
+"[b]注æ„:[/b]å¯ç”¨è¿™ä¸ªè®¾ç½®ä¸ä¼šæå‡æ¸²æŸ“è´¨é‡ã€‚ä½¿ç”¨å®Œæ•´æµ®ç‚¹æ•°ç²¾åº¦è¾ƒæ…¢ï¼Œä¸€èˆ¬åªæœ‰è¦"
+"求更高精度的高级ç€è‰²å™¨éœ€è¦ä½¿ç”¨ã€‚如果是è¦å‡å°‘æ¡å¸¦æ•ˆåº”,请å¯ç”¨ [member "
+"rendering/quality/filters/use_debanding]。\n"
+"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸­å¯ç”¨ã€‚"
#: doc/classes/ProjectSettings.xml
msgid ""
@@ -59721,13 +60142,12 @@ msgid "2D axis-aligned bounding box."
msgstr "2D 轴对é½è¾¹ç•Œæ¡†ã€‚"
#: doc/classes/Rect2.xml
+#, fuzzy
msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
"[Rect2] ç”±ä¸€ä¸ªåæ ‡ã€ä¸€ä¸ªå¤§å°å’Œå‡ ä¸ªå®žç”¨å‡½æ•°ç»„æˆã€‚它通常用于快速é‡å æµ‹è¯•。\n"
"å®ƒä½¿ç”¨æµ®ç‚¹åæ ‡ã€‚\n"
@@ -62671,7 +63091,6 @@ msgid "Groups [Room]s together to allow common functionality."
msgstr "å°† [Room] 组åˆåœ¨ä¸€èµ·ä»¥å®žçŽ°é€šç”¨åŠŸèƒ½ã€‚"
#: doc/classes/RoomGroup.xml
-#, fuzzy
msgid ""
"Although [Room] behavior can be specified individually, sometimes it is "
"faster and more convenient to write functionality for a group of rooms.\n"
@@ -62686,14 +63105,14 @@ msgid ""
"[code]notification[/code]s as they enter and exit the [b]gameplay area[/b] "
"(see [RoomManager] for details)."
msgstr ""
-"尽管å¯ä»¥å•独指定 [Room] 行为,但有时为一组空间编写功能会更快更方便。\n"
-"[RoomGroup] 应作为[b]空间列表[/b](您的 [Room] 的父 [Node])的å­é¡¹è€Œè®¾ç½®ï¼Œè€Œ "
-"[Room] 应作为 [RoomGroup] çš„å­é¡¹ä¾æ¬¡è®¾ç½®ä»¥ä¾¿å°†å®ƒä»¬åˆ†é…ç»™ RoomGroup。\n"
+"尽管å¯ä»¥å•独指定 [Room] 行为,但有时为一组房间编写功能会更快更方便。\n"
+"[RoomGroup] 应作为[b]空间列表[/b](您的 [Room] 的父 [Node])的å­é¡¹ï¼Œè€Œ "
+"[Room] 应作为 [RoomGroup] çš„å­é¡¹ä¾æ¬¡æ”¾ç½®ä»¥ä¾¿å°†å®ƒä»¬åˆ†é…ç»™ RoomGroup。\n"
"例如,[RoomGroup] å¯ç”¨äºŽæŒ‡å®š[b]处于外部[/b]çš„ [Room],并在玩家进入/退出该区域"
"时打开或关闭定å‘å…‰ã€å¤©ç©ºæˆ–雨效果。\n"
-"当 [code]gameplay_monitor[/code] 开坿—¶ï¼Œ[RoomGroup] 收到[b]游æˆå›žè°ƒ[/b],在"
-"他们进入和退出[b]游æˆåŒºåŸŸ[/b]时,以[code]ä¿¡å·[/code]或[code]通知[/code]的形å¼"
-"ï¼ˆè¯¦è§ [RoomManager])。"
+"当 [code]gameplay_monitor[/code] 开坿—¶ï¼Œ[RoomGroup] å¯ä»¥æ”¶åˆ°[b]游æˆå›žè°ƒ[/"
+"b],在他们进入和退出[b]游æˆåŒºåŸŸ[/b]时,以[code]ä¿¡å·[/code]或[code]通知[/code]"
+"的形å¼ï¼ˆè¯¦è§ [RoomManager])。"
#: doc/classes/RoomGroup.xml
msgid ""
@@ -62926,9 +63345,9 @@ msgid ""
"level. Here you can alter the threshold at which the editor warning appears. "
"There are no other side effects."
msgstr ""
-"转æ¢ç©ºé—´æ—¶ï¼Œå¦‚果检测到空间之间有é‡å ï¼Œç¼–辑器会警告您。é‡å ä¼šå¹²æ‰°ç¡®å®šæ‘„åƒæœºå’Œ"
-"ç‰©ä½“æ‰€åœ¨çš„ç©ºé—´ã€‚æ ¹æ®æ‚¨çš„levelï¼Œå°‘é‡æ˜¯å¯ä»¥æŽ¥å—的。您å¯ä»¥åœ¨æ­¤å¤„更改出现编辑器警"
-"告的阈值。没有其他副作用。"
+"è½¬æ¢æˆ¿é—´æ—¶ï¼Œå¦‚果检测到空间之间有é‡å ï¼Œç¼–辑器会警告您。é‡å ä¼šå¹²æ‰°ç¡®å®šæ‘„åƒæœºå’Œ"
+"ç‰©ä½“æ‰€åœ¨çš„ç©ºé—´ã€‚æ ¹æ®æ‚¨çš„ levelï¼Œå°‘é‡æ˜¯å¯ä»¥æŽ¥å—的。您å¯ä»¥åœ¨æ­¤å¤„更改出现编辑器"
+"警告的阈值。没有其他副作用。"
#: doc/classes/RoomManager.xml
msgid ""
@@ -62943,16 +63362,15 @@ msgstr ""
"[b]注æ„:[/b]使用 [code]Full[/code] PVS æ¨¡å¼æ—¶ä¸ä½¿ç”¨è¯¥å€¼ã€‚"
#: doc/classes/RoomManager.xml
-#, fuzzy
msgid ""
"Portal culling normally operates using the current [Camera] / [Camera]s, "
"however for debugging purposes within the editor, you can use this setting "
"to override this behavior and force it to use a particular camera to get a "
"better idea of what the occlusion culling is doing."
msgstr ""
-"Portal 剔除通常使用当å‰çš„ [Camera] / 多个[Camera] 进行æ“作,但是为了在编辑器"
-"中进行调试,您å¯ä»¥ä½¿ç”¨æ­¤è®¾ç½®æ¥è¦†ç›–此行为并强制它使用特定的相机以更好地了解é®"
-"挡的内容剔除正在åšã€‚"
+"å…¥å£å‰”除通常使用当å‰çš„ [Camera] 或多个 [Camera] 进行æ“作,但是为了在编辑器中"
+"进行调试,您å¯ä»¥ä½¿ç”¨æ­¤è®¾ç½®æ¥è¦†ç›–此行为并强制它使用特定的相机,以更好地了解é®"
+"挡剔除的效果。"
#: doc/classes/RoomManager.xml
msgid ""
@@ -63055,8 +63473,8 @@ msgid ""
"Use only [Portal]s at runtime to determine visibility. PVS will not be "
"generated at [Room]s conversion, and gameplay notifications cannot be used."
msgstr ""
-"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚ [Room]的转æ¢ä¸ä¼šäº§ç”ŸPVS,无法使用游æˆ"
-"通知。"
+"在è¿è¡Œæ—¶ä»…使用 [Portal] æ¥ç¡®å®šå¯è§æ€§ã€‚ [Room] 的转æ¢ä¸ä¼šäº§ç”Ÿ PVS,无法使用游"
+"æˆé€šçŸ¥ã€‚"
#: doc/classes/RoomManager.xml
msgid ""
@@ -63075,7 +63493,6 @@ msgid "Editor-only helper for setting up root motion in [AnimationTree]."
msgstr "在[AnimationTree]中设置根è¿åŠ¨çš„ä»…ç¼–è¾‘å™¨å¯ç”¨çš„辅助工具。"
#: doc/classes/RootMotionView.xml
-#, fuzzy
msgid ""
"[i]Root motion[/i] refers to an animation technique where a mesh's skeleton "
"is used to give impulse to a character. When working with 3D animations, a "
@@ -63090,14 +63507,14 @@ msgid ""
"[code]extends RootMotionView[/code]. Additionally, it must not be a "
"[code]tool[/code] script."
msgstr ""
-"[i]Root motion[/i] 指的是一ç§åŠ¨ç”»æŠ€æœ¯ï¼Œå…¶ä¸­ä½¿ç”¨ç½‘æ ¼çš„éª¨æž¶ä¸ºè§’è‰²æä¾›åŠ¨åŠ›ã€‚åœ¨å¤„"
-"ç† 3D åŠ¨ç”»æ—¶ï¼Œä¸€ç§æµè¡Œçš„æŠ€æœ¯æ˜¯åŠ¨ç”»å¸ˆä½¿ç”¨æ ¹éª¨æž¶éª¨éª¼æ¥ä¸ºéª¨æž¶çš„其余部分æä¾›è¿"
-"动。这å…许以步骤实际匹é…下方地æ¿çš„æ–¹å¼ä¸ºè§’色设置动画。它还å…许在过场动画期间"
-"与对象进行精确交互。å¦è§[AnimationTree]。\n"
-"[b]注æ„:[/b] [RootMotionView] 仅在编辑器中å¯è§ã€‚在è¿è¡Œçš„项目中会自动éšè—,在"
-"è¿è¡Œçš„项目中也会转æ¢ä¸ºæ™®é€šçš„[Node]。这æ„味ç€é™„加到 [RootMotionView] 节点的脚"
-"本 [i] å¿…é¡» [/i] 具有 [code]继承节点[/code] è€Œä¸æ˜¯ [code]继承 "
-"RootMotionView[/code]。此外,它ä¸èƒ½æ˜¯ [code]@tool[/code] 脚本。"
+"[i]æ ¹è¿åЍ[/i](Root Motion)指的是一ç§åŠ¨ç”»æŠ€æœ¯ï¼Œå…¶ä¸­ä½¿ç”¨ç½‘æ ¼çš„éª¨æž¶ä¸ºè§’è‰²æä¾›"
+"åŠ¨åŠ›ã€‚åœ¨å¤„ç† 3D åŠ¨ç”»æ—¶ï¼Œä¸€ç§æµè¡Œçš„æŠ€æœ¯æ˜¯åŠ¨ç”»å¸ˆä½¿ç”¨æ ¹éª¨æž¶éª¨éª¼æ¥ä¸ºéª¨æž¶çš„其余部"
+"分æä¾›è¿åŠ¨ã€‚è¿™å…许以步骤实际匹é…下方地æ¿çš„æ–¹å¼ä¸ºè§’色设置动画。它还å…许在过场"
+"动画期间与对象进行精确交互。å¦è§ [AnimationTree]。\n"
+"[b]注æ„:[/b][RootMotionView] 仅在编辑器中å¯è§ã€‚在è¿è¡Œçš„项目中会自动éšè—,在"
+"è¿è¡Œçš„项目中也会转æ¢ä¸ºæ™®é€šçš„ [Node]。这æ„味ç€é™„加到 [RootMotionView] 节点的脚"
+"本[i]å¿…é¡»[/i]具写 [code]extends Node[/code] è€Œä¸æ˜¯ [code]extends "
+"RootMotionView[/code]。此外,它ä¸èƒ½æ˜¯ [code]tool[/code] 脚本。"
#: doc/classes/RootMotionView.xml
msgid "$DOCS_URL/tutorials/animation/animation_tree.html#root-motion"
@@ -63168,7 +63585,8 @@ msgid ""
"Returns the connection flags for the signal at [code]idx[/code]. See [enum "
"Object.ConnectFlags] constants."
msgstr ""
-"返回[code]idx[/code]处的信å·çš„连接标志。å‚阅[enum Object.ConnectFlags]常数。"
+"返回 [code]idx[/code] 处的信å·çš„连接标志。请å‚阅 [enum Object.ConnectFlags] "
+"常é‡ã€‚"
#: doc/classes/SceneState.xml
msgid "Returns the method connected to the signal at [code]idx[/code]."
@@ -64089,6 +64507,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr "当用户更改活动脚本时å‘å‡ºã€‚å‚æ•°æ˜¯æ–°æ¿€æ´»çš„ [Script]。"
@@ -65042,14 +65466,25 @@ msgid ""
"values."
msgstr "如果为 [code]true[/code],则滑动æ¡å°†æ˜¾ç¤ºæœ€å°å€¼å’Œæœ€å¤§å€¼çš„刻度。"
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+#, fuzzy
+msgid "Emitted when dragging is started."
+msgstr "滚动开始时å‘出。"
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
-msgstr "在3D中两个物ç†ä½“之间的滑å—。"
+msgstr "3D 中,两个 PhysicsBody 之间的滑动æ¡ã€‚"
#: doc/classes/SliderJoint.xml
msgid ""
"Slides across the X axis of the pivot object. See also [Generic6DOFJoint]."
-msgstr "在枢轴对象的X轴上滑动。å‚阅[Generic6DOFJoint]。"
+msgstr "在轴心对象的 X 轴上滑动。å‚阅 [Generic6DOFJoint]。"
#: doc/classes/SliderJoint.xml
msgid ""
@@ -65083,7 +65518,7 @@ msgstr "应用于所有å—陿—‹è½¬çš„系数。"
#: doc/classes/SliderJoint.xml
msgid ""
"A factor applied to the all rotation across axes orthogonal to the slider."
-msgstr "åº”ç”¨äºŽä¸Žæ»‘å—æ­£äº¤çš„轴的所有旋转的系数。"
+msgstr "åº”ç”¨äºŽä¸Žæ»‘åŠ¨æ¡æ­£äº¤çš„轴的所有旋转的系数。"
#: doc/classes/SliderJoint.xml
msgid ""
@@ -65245,33 +65680,34 @@ msgid ""
"Rotates the global (world) transformation around axis, a unit [Vector3], by "
"specified angle in radians. The rotation axis is in global coordinate system."
msgstr ""
-"围绕轴(一个å•ä½[Vector3]ï¼‰æ—‹è½¬å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢ï¼ŒæŒ‡å®šè§’度(弧度)。旋转轴是在"
-"免局忠‡ç³»ä¸­ã€‚"
+"å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢å›´ç»•æŸä¸ªè½´ï¼ˆå•ä½ [Vector3])旋转指定的弧度。旋转轴使用全局"
+"åæ ‡ç³»ã€‚"
#: doc/classes/Spatial.xml
msgid ""
"Scales the global (world) transformation by the given [Vector3] scale "
"factors."
-msgstr "通过给定的 [Vector3] 比例因å­å¯¹å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢è¿›è¡Œç¼©æ”¾ã€‚"
+msgstr "å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢æŒ‰ç…§ç»™å®šçš„ [Vector3] 缩放因å­è¿›è¡Œç¼©æ”¾ã€‚"
#: doc/classes/Spatial.xml
msgid ""
"Moves the global (world) transformation by [Vector3] offset. The offset is "
"in global coordinate system."
-msgstr "通过 [Vector3] åç§»é‡ç§»åŠ¨å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢ã€‚åç§»é‡æ˜¯åœ¨å…¨å±€å标系中。"
+msgstr ""
+"å°†å…¨å±€ï¼ˆä¸–ç•Œï¼‰å˜æ¢æŒ‰ç…§ [Vector3] åç§»é‡è¿›è¡Œç§»åŠ¨ã€‚åç§»é‡ä½¿ç”¨å…¨å±€å标系。"
#: doc/classes/Spatial.xml
msgid ""
"Disables rendering of this node. Changes [member visible] to [code]false[/"
"code]."
-msgstr "ç¦ç”¨è¯¥èŠ‚ç‚¹çš„æ¸²æŸ“ã€‚å®ƒå°†[member visible]改为[code]false[/code]。"
+msgstr "ç¦ç”¨è¯¥èŠ‚ç‚¹çš„æ¸²æŸ“ã€‚ä¼šå°† [member visible] 改为 [code]false[/code]。"
#: doc/classes/Spatial.xml
msgid ""
"Returns whether node notifies about its local transformation changes. "
"[Spatial] will not propagate this by default."
msgstr ""
-"返回节点是å¦é€šçŸ¥å…¶å±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial]默认情况下ä¸ä¼šå¯¹æ­¤è¿›è¡Œä¼ æ’­ã€‚"
+"返回节点是å¦é€šçŸ¥å…¶å±€éƒ¨å˜æ¢çš„å˜åŒ–。[Spatial] 默认情况下ä¸ä¼šå¯¹æ­¤è¿›è¡Œä¼ æ’­ã€‚"
#: doc/classes/Spatial.xml
msgid ""
@@ -65341,15 +65777,15 @@ msgstr ""
#: doc/classes/Spatial.xml
msgid "Rotates the local transformation around the X axis by angle in radians."
-msgstr "围绕Xè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
+msgstr "围绕 X è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
#: doc/classes/Spatial.xml
msgid "Rotates the local transformation around the Y axis by angle in radians."
-msgstr "围绕Yè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
+msgstr "围绕 Y è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
#: doc/classes/Spatial.xml
msgid "Rotates the local transformation around the Z axis by angle in radians."
-msgstr "围绕Zè½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
+msgstr "围绕 Z è½´æ—‹è½¬å±€éƒ¨å˜æ¢ï¼Œæ—‹è½¬è§’度为弧度。"
#: doc/classes/Spatial.xml
msgid ""
@@ -65438,7 +65874,7 @@ msgstr "通过给定的åç§»é‡[Vector3]改å˜èŠ‚ç‚¹åœ¨å±€éƒ¨ç©ºé—´ä¸­çš„ä½ç½®
#: doc/classes/Spatial.xml
msgid "Updates the [SpatialGizmo] of this node."
-msgstr "更新该节点的[SpatialGizmo]。"
+msgstr "更新该节点的 [SpatialGizmo]。"
#: doc/classes/Spatial.xml
msgid ""
@@ -65603,7 +66039,6 @@ msgstr ""
"å¯ä»¥é€šè¿‡å°†ç›¸åº”çš„æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨åŠŸèƒ½ã€‚"
#: doc/classes/SpatialMaterial.xml
-#, fuzzy
msgid ""
"If [code]true[/code], enables the specified flag. Flags are optional "
"behavior that can be turned on and off. Only one flag can be enabled at a "
@@ -65612,10 +66047,10 @@ msgid ""
"setting the corresponding member to [code]true[/code]. See [enum Flags] "
"enumerator for options."
msgstr ""
-"如果 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„æ ‡å¿—。标志是å¯ä»¥æ‰“开和关闭的å¯é€‰è¡Œä¸ºã€‚使"
-"用该函数一次åªèƒ½å¯ç”¨ä¸€ä¸ªæ ‡å¿—,ä¸èƒ½å°†æ ‡å¿—æžšä¸¾å™¨è¿›è¡Œä½æŽ©ç ï¼Œä»¥ä¸€æ¬¡å¯ç”¨æˆ–ç¦ç”¨å¤š"
-"个标志。也å¯ä»¥é€šè¿‡å°†ç›¸åº”æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨æ ‡å¿—。有关选项,请"
-"å‚阅 [enum Flags] 枚举器。"
+"如果为 [code]true[/code],则å¯ç”¨æŒ‡å®šçš„æ ‡å¿—。标志是å¯ä»¥æ‰“开和关闭的å¯é€‰è¡Œä¸ºã€‚"
+"使用该函数一次åªèƒ½å¯ç”¨ä¸€ä¸ªæ ‡å¿—,ä¸èƒ½å°†æ ‡å¿—枚举值åƒä½æŽ©ç ä¸€æ ·è¿›è¡Œåˆå¹¶ï¼Œä¸€æ¬¡å¯"
+"用或ç¦ç”¨å¤šä¸ªæ ‡å¿—。也å¯ä»¥é€šè¿‡å°†ç›¸åº”æˆå‘˜è®¾ç½®ä¸º [code]true[/code] æ¥å¯ç”¨æ ‡å¿—。有"
+"关选项,请å‚阅 [enum Flags] 枚举器。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -65641,6 +66076,8 @@ msgid ""
"anisotropy_flowmap]'s alpha channel if a texture is defined there and the "
"texture contains an alpha channel."
msgstr ""
+"å„å‘异性效果的强度。如果 [member anisotropy_flowmap] 是一张带有 Alpha 通é“çš„"
+"纹ç†ï¼Œé‚£ä¹ˆè¿™ä¸ªå€¼ä¼šä¸Žå…¶ Alpha 通é“相乘。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -65654,6 +66091,13 @@ msgid ""
"a texture in the FileSystem dock, going to the Import dock, checking the "
"[b]Anisotropic[/b] checkbox then clicking [b]Reimport[/b]."
msgstr ""
+"如果为 [code]true[/code],则å¯ç”¨å„å‘异性。å„å‘异性会改å˜é«˜å…‰ç‚¹çš„形状并将其与"
+"切线空间对其。å¯ç”¨äºŽæ‹‰ä¸é“æå’Œæ¯›å‘å射。\n"
+"[b]注æ„:[/b]å„å‘异性需è¦ç½‘格切线æ‰èƒ½æ­£å¸¸å·¥ä½œã€‚如果网格中ä¸åŒ…å«åˆ‡çº¿ï¼Œå„å‘异性"
+"效果就会看上去有问题。\n"
+"[b]注æ„:[/b]æè´¨çš„å„å‘异性ä¸åº”与纹ç†çš„å„å‘异性过滤相混淆。纹ç†å„å‘异性过滤的"
+"å¯ç”¨æ–¹æ³•是,在“文件系统â€é¢æ¿ä¸­é€‰ä¸­çº¹ç†ï¼Œç„¶åŽåœ¨â€œå¯¼å…¥â€é¢æ¿ä¸­å‹¾é€‰ "
+"[b]Anisotropic[/b] å¤é€‰æ¡†ï¼Œç„¶åŽç‚¹å‡»[b]釿–°å¯¼å…¥[/b]。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -65669,6 +66113,13 @@ msgid ""
"will disable the anisotropy effect entirely. The flowmap texture's blue "
"channel is ignored."
msgstr ""
+"用于对切线图进行å移的纹ç†ï¼Œç”¨äºŽå„å‘异性的计算,(如果存在 Alpha 通é“)还å¯ä»¥"
+"控制å„å‘异性的效果。Flowmap æ–¹å‘图纹ç†åº”该是一张派生图,红色通é“表示 X 轴上的"
+"å˜å½¢ã€ç»¿è‰²é€šé“表示 Y 轴上的å˜å½¢ã€‚å°äºŽ 0.5 的值会æœè´Ÿæ–¹å‘进行å˜å½¢ï¼Œè€Œå¤§äºŽ 0.5 "
+"çš„å€¼åˆ™æœæ­£æ–¹å‘å˜å½¢ã€‚\n"
+"纹ç†çš„ Alpha 通é“如果存在,则会用于与 [member anisotropy] 效果的强度相乘。完"
+"å…¨ä¸é€æ˜Žçš„åƒç´ ä¼šä¿æŒåŽŸå§‹å¼ºåº¦ï¼Œè€Œå®Œå…¨é€æ˜Žçš„åƒç´ åˆ™ä¼šå®Œå…¨ç¦ç”¨å„å‘异性效果。方å‘"
+"图纹ç†çš„è“色通é“会被忽略。"
#: doc/classes/SpatialMaterial.xml
msgid ""
@@ -65866,9 +66317,10 @@ msgid ""
msgstr "纹ç†ç”¨äºŽæŒ‡å®šç»†èŠ‚çº¹ç†ä¸ŽåŸºç¡€çº¹ç†çš„æ··åˆæ–¹å¼ã€‚"
#: doc/classes/SpatialMaterial.xml
+#, fuzzy
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -66101,6 +66553,7 @@ msgid "The strength of the normal map's effect."
msgstr "法线贴图的效果强度。"
#: doc/classes/SpatialMaterial.xml
+#, fuzzy
msgid ""
"Texture used to specify the normal at a given pixel. The "
"[code]normal_texture[/code] only uses the red and green channels; the blue "
@@ -66112,7 +66565,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -67431,13 +67884,15 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr "代表[enum DrawFlags]枚举的大å°ã€‚"
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+#, fuzzy
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr "AnimatedSprite 的精çµå¸§åº“。"
#: doc/classes/SpriteFrames.xml
+#, fuzzy
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -67673,14 +68128,14 @@ msgstr ""
"@GlobalScope.Error] 错误ç ä»¥åŠä¸€ä¸ªæ•°æ®æ•°ç»„。"
#: doc/classes/StreamPeer.xml
-#, fuzzy
msgid ""
"Gets an ASCII string with byte-length [code]bytes[/code] from the stream. If "
"[code]bytes[/code] is negative (default) the length will be read from the "
"stream using the reverse process of [method put_string]."
msgstr ""
-"从æµä¸­èŽ·å–一个字节长度为 [code]bytes[/code] 的字符串。如果 [code]bytes[/"
-"code] 为负(默认),会按照 [method put_string] çš„é€†å‘æ“作从æµä¸­è¯»å–长度。"
+"从æµä¸­èŽ·å–一个字节长度为 [code]bytes[/code] çš„ ASCII 字符串。如果 "
+"[code]bytes[/code] 为负(默认),会按照 [method put_string] çš„é€†å‘æ“作从æµä¸­"
+"读å–长度。"
#: doc/classes/StreamPeer.xml
msgid "Gets an unsigned 16-bit value from the stream."
@@ -68526,6 +68981,12 @@ msgid ""
"print(\", \".join([\"One\", \"Two\", \"Three\", \"Four\"]))\n"
"[/codeblock]"
msgstr ""
+"返回将 [code]parts[/code] 相连åŽå¾—到的 [String]。元素之间的分隔符是æä¾›è¿™ä¸ªæ–¹"
+"法的字符串。\n"
+"示例:\n"
+"[codeblock]\n"
+"print(\", \".join([\"One\", \"Two\", \"Three\", \"Four\"]))\n"
+"[/codeblock]"
#: doc/classes/String.xml
msgid ""
@@ -70001,8 +70462,8 @@ msgid ""
"[code]visible[/code] property is set to [code]true[/code] and all others are "
"set to [code]false[/code]."
msgstr ""
-"当剿 ‡ç­¾ç´¢å¼•。设置åŽï¼Œæ­¤ç´¢å¼•çš„ [Control] 节点的 [code]visible[/code] 属性设置"
-"为 [code]true[/code],其他所有设置为 [code]false[/code]。"
+"当å‰é€‰é¡¹å¡çš„索引。设置åŽï¼Œæ­¤ç´¢å¼•çš„ [Control] 节点的 [code]visible[/code] 属性"
+"会被设为 [code]true[/code],其他所有都设置为 [code]false[/code]。"
#: doc/classes/TabContainer.xml doc/classes/Tabs.xml
msgid "If [code]true[/code], tabs can be rearranged with mouse drag."
@@ -72446,7 +72907,6 @@ msgstr ""
"å¯ä»¥é€‰æ‹©å¿½ç•¥å›¾å—地图的åŠå移。"
#: doc/classes/TileMap.xml
-#, fuzzy
msgid ""
"Sets the tile index for the given cell.\n"
"An index of [code]-1[/code] clears the cell.\n"
@@ -72467,23 +72927,22 @@ msgid ""
" .set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)\n"
"[/codeblock]"
msgstr ""
-"设置由Vector2给出的å•元格的图å—索引。\n"
-"[code]-1[/code]的索引将清除该å•元。\n"
-"也å¯ä»¥é€‰æ‹©ç¿»è½¬ã€ç§»ä½ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å­å›¾å—的列和"
-"行。\n"
-"[b]注æ„:[/b] 由于性能原因,导航多边形和碰撞形状等数æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n"
-"如果你需è¦è¿™äº›è¢«ç«‹å³æ›´æ–°ï¼Œä½ å¯ä»¥è°ƒç”¨[method update_dirty_quadrants]。\n"
+"为给定的å•元格设置图å—索引。\n"
+"索引 [code]-1[/code] 会清除该å•元格。\n"
+"也å¯ä»¥å¯¹å›¾å—进行翻转ã€è½¬ç½®ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å­å›¾å—çš„"
+"列和行。\n"
+"[b]注æ„:[/b]由于性能原因,导航多边形和碰撞形状等数æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n"
+"如果需è¦ç«‹å³æ›´æ–°ï¼Œä½ å¯ä»¥è°ƒç”¨ [method update_dirty_quadrants]。\n"
"é‡å†™è¯¥æ–¹æ³•会在内部é‡å†™å®ƒï¼Œå…许在放置/ç§»é™¤å›¾å—æ—¶å®žçŽ°è‡ªå®šä¹‰é€»è¾‘ã€‚\n"
"[codeblock]\n"
"func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, "
"autotile_coord=Vector2()):\n"
" # 在这里写下你的自定义逻辑。 \n"
-" # 调用默认方法:\n"
+" # 调用默认方法:\n"
" .set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)\n"
"[/codeblock]"
#: doc/classes/TileMap.xml
-#, fuzzy
msgid ""
"Sets the tile index for the cell given by a Vector2.\n"
"An index of [code]-1[/code] clears the cell.\n"
@@ -72495,11 +72954,12 @@ msgid ""
"If you need these to be immediately updated, you can call [method "
"update_dirty_quadrants]."
msgstr ""
-"设置给定å•元格的瓦片索引。\n"
-"索引[code]-1[/code]会清除该å•元。\n"
-"也å¯ä»¥é€‰æ‹©ç¿»è½¬æˆ–转置图å—。\n"
-"[b]注æ„:[/b] 由于性能原因,导航多边形和碰撞形状等数æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n"
-"如果你需è¦ç«‹å³æ›´æ–°è¿™äº›æ•°æ®ï¼Œå¯ä»¥è°ƒç”¨[method update_dirty_quadrants]。"
+"为通过 Vector2 给定的å•元格设置图å—索引。\n"
+"索引 [code]-1[/code] 会清除该å•元格。\n"
+"也å¯ä»¥å¯¹å›¾å—进行翻转ã€è½¬ç½®ï¼Œæˆ–者指定自动图å—åæ ‡ã€‚自动图å—åæ ‡æŒ‡çš„æ˜¯å­å›¾å—çš„"
+"列和行。\n"
+"[b]注æ„:[/b]由于性能原因,导航多边形和碰撞形状等数æ®ä¸ä¼šç«‹å³æ›´æ–°ã€‚\n"
+"如果你需è¦ç«‹å³æ›´æ–°è¿™äº›æ•°æ®ï¼Œå¯ä»¥è°ƒç”¨ [method update_dirty_quadrants]。"
#: doc/classes/TileMap.xml
msgid "Sets the given collision layer bit."
@@ -72666,16 +73126,16 @@ msgid ""
"option, because displacing textures with the [member cell_tile_origin] "
"option or in irregular tiles is not relevant when centering those textures."
msgstr ""
-"如果[code]为true[/code]ï¼Œåˆ™ä¿æŒä¸ŽGodot 3.1或更早版本的图å—地图的兼容性,å³å½“"
-"图å—åŽŸç‚¹æ”¹å˜æ—¶ï¼Œçº¹ç†ä¼šç§»åŠ¨ï¼Œå¦‚æžœçº¹ç†å¤§å°ä¸å‡åŒ€ï¼Œåˆ™ä¼šæ—‹è½¬ã€‚è¿™ç§æ¨¡å¼å¯¹éžåŒè´¨ç­‰"
-"è·å›¾å—(例如2:1)进行[code]flip_h[/code], [code]flip_v[/code] å’Œ "
+"如果为 [code]true[/code]ï¼Œåˆ™ä¿æŒä¸Ž Godot 3.1 或更早版本的图å—地图的兼容性,å³"
+"当图å—åŽŸç‚¹æ”¹å˜æ—¶ï¼Œçº¹ç†ä¼šç§»åŠ¨ï¼Œå¦‚æžœçº¹ç†å¤§å°ä¸å‡åŒ€ï¼Œåˆ™ä¼šæ—‹è½¬ã€‚è¿™ç§æ¨¡å¼å¯¹éžåŒè´¨"
+"ç­‰è·å›¾å—(例如 2:1)进行 [code]flip_h[/code]ã€[code]flip_v[/code]ã€"
"[code]transpose[/code] 图嗿“ä½œæ—¶ï¼Œå°†å‡ºçŽ°é—®é¢˜ï¼Œåœ¨è¿™ç§æƒ…况下,纹ç†ä¸èƒ½ä¸Žç¢°æ’žé‡"
"åˆï¼Œå› æ­¤ä¸æŽ¨èç”¨äºŽç­‰è·æˆ–éžæ–¹å½¢å›¾å—。\n"
-"如果[code]false[/code],在进行[code]flip_h[/code]ã€[code]flip_v[/code]æ“作"
-"时,如果ä¸ä½¿ç”¨åç§»é‡ï¼Œçº¹ç†ä¸ä¼šç§»åŠ¨ï¼Œåœ¨æ”¹å˜å›¾å—原点时也是如此。\n"
-"兼容性模å¼å¯¹[member centered_textures]选项ä¸èµ·ä½œç”¨ï¼Œå› ä¸ºç”¨[member "
-"cell_tile_origin]选项或ä¸è§„则图å—中的纹ç†è¿›è¡Œæ›¿æ¢æ—¶ï¼Œä¸Žè¿™äº›çº¹ç†çš„居中项没有关"
-"系。"
+"如果为 [code]false[/code],则在进行 [code]flip_h[/code]ã€[code]flip_v[/code] "
+"æ“作时,如果ä¸ä½¿ç”¨åç§»é‡ï¼Œçº¹ç†ä¸ä¼šç§»åŠ¨ï¼Œåœ¨æ”¹å˜å›¾å—原点时也是如此。\n"
+"兼容性模å¼å¯¹ [member centered_textures] 选项ä¸èµ·ä½œç”¨ï¼Œå› ä¸ºç”¨ [member "
+"cell_tile_origin] 选项或ä¸è§„则图å—中的纹ç†è¿›è¡Œæ›¿æ¢æ—¶ï¼Œä¸Žè¿™äº›çº¹ç†çš„居中项没有"
+"关系。"
#: doc/classes/TileMap.xml
msgid "The TileMap orientation mode. See [enum Mode] for possible values."
@@ -75172,6 +75632,7 @@ msgid "Smoothly animates a node's properties over time."
msgstr "ä½¿èŠ‚ç‚¹çš„å±žæ€§éšæ—¶é—´å¹³æ»‘地å˜åŒ–。"
#: doc/classes/Tween.xml
+#, fuzzy
msgid ""
"Tweens are useful for animations requiring a numerical property to be "
"interpolated over a range of values. The name [i]tween[/i] comes from [i]in-"
@@ -75205,7 +75666,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
"需è¦è®©æ•°å€¼å±žæ€§åœ¨ä¸€å®šèŒƒå›´å†…åšæ’值的动画å¯ä»¥ä½¿ç”¨ Tween。[i]Tween[/i] 这个åå­—æ¥"
"自动画技术 [i]in-betweening[/i](补间动画):你指定[i]关键帧[/i],而计算机则"
@@ -75468,9 +75931,9 @@ msgid ""
"code] for half of the normal speed. A value of [code]0[/code] pauses the "
"animation, but see also [method set_active] or [method stop_all] for this."
msgstr ""
-"补间的速度乘数。例如,设置为[code]1.0[/code]为正常速度,[code]2.0[/code]为正"
-"常速度的2å€ï¼Œæˆ–者[code]0.5[/code]为正常速度的一åŠã€‚值为[code]0[/code]时,动画"
-"会暂åœï¼Œå¦è¯·å‚阅[method set_active]或[method stop_all]。"
+"补间的速度乘数。例如,设置为 [code]1.0[/code] 为正常速度,[code]2.0[/code] 为"
+"正常速度的 2 å€ï¼Œæˆ–者 [code]0.5[/code] 为正常速度的一åŠã€‚值为 [code]0[/code] "
+"时,动画会暂åœï¼Œå¦è¯·å‚阅 [method set_active] 或 [method stop_all]。"
#: doc/classes/Tween.xml
msgid "If [code]true[/code], the tween loops."
@@ -76692,8 +77155,17 @@ msgstr ""
"通过é™åˆ¶å…¶é•¿åº¦ä¸º [code]length[/code],返回具有最大长度的å‘é‡ã€‚"
#: doc/classes/Vector2.xml
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "返回此å‘é‡ä¸Ž[code]with[/code]çš„å‰ç§¯ã€‚"
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
@@ -76801,11 +77273,12 @@ msgstr ""
"code]。[code]weight[/code]的范围是0.0到1.0,表示æ’值的数é‡ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
-#, fuzzy
msgid ""
"Returns a new vector moved toward [code]to[/code] by the fixed [code]delta[/"
"code] amount. Will not go past the final value."
-msgstr "å‘[code]to[/code]移动固定的[code]delta[/code]é‡ã€‚"
+msgstr ""
+"è¿”å›žå‘ [code]to[/code] 移动固定的 [code]delta[/code] é‡åŽçš„æ–°å‘é‡ã€‚ä¸ä¼šè¶…过最"
+"终值。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -76830,16 +77303,16 @@ msgstr ""
"çš„å‘é‡ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
-#, fuzzy
msgid "Returns this vector projected onto the vector [code]b[/code]."
-msgstr "返回投射到å‘é‡[code]b[/code]çš„å‘é‡ã€‚"
+msgstr "返回投射到å‘é‡ [code]b[/code] çš„å‘é‡ã€‚"
#: doc/classes/Vector2.xml
-#, fuzzy
msgid ""
"Returns the vector reflected (i.e. mirrored, or symmetric) over a line "
"defined by the given direction vector [code]n[/code]."
-msgstr "返回从给定法线定义的平é¢åå°„çš„å‘é‡ã€‚"
+msgstr ""
+"返回ç»è¿‡ç”±ç»™å®šçš„æ–¹å‘å‘é‡ [code]n[/code] 定义的线åå°„åŽçš„(å³é•œåƒæˆ–对称)å‘"
+"é‡ã€‚"
#: doc/classes/Vector2.xml
msgid ""
@@ -76848,7 +77321,6 @@ msgid ""
msgstr "返回旋转了[code]phi[/code]弧度的å‘é‡ã€‚å‚阅[method @GDScript.deg2rad]。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
-#, fuzzy
msgid ""
"Returns a new vector with all components rounded to the nearest integer, "
"with halfway cases rounded away from zero."
@@ -76856,13 +77328,13 @@ msgstr ""
"返回所有分é‡éƒ½è¢«å››èˆäº”入为最接近的整数的å‘é‡ï¼Œä¸­é—´æƒ…况å‘远离零的方å‘èˆå…¥ã€‚"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
-#, fuzzy
msgid ""
"Returns a new vector with each component set to one or negative one, "
"depending on the signs of the components. If a component is zero, it returns "
"positive one."
msgstr ""
-"æ ¹æ®åˆ†é‡çš„符å·ï¼Œè¿”回æ¯ä¸ªåˆ†é‡è®¾ç½®ä¸º 1 或负1çš„å‘é‡ã€‚如果分é‡ä¸ºé›¶ï¼Œåˆ™è¿”回正1。"
+"æ ¹æ®åˆ†é‡çš„符å·ï¼Œè¿”回æ¯ä¸ªåˆ†é‡è®¾ç½®ä¸º 1 或负 1 çš„å‘é‡ã€‚如果分é‡ä¸ºé›¶ï¼Œåˆ™è¿”回正 "
+"1。"
#: doc/classes/Vector2.xml doc/classes/Vector3.xml
msgid ""
@@ -76974,16 +77446,15 @@ msgid "Returns the cross product of this vector and [code]b[/code]."
msgstr "返回此å‘é‡ä¸Ž [code]b[/code] çš„å‰ç§¯ã€‚"
#: doc/classes/Vector3.xml
-#, fuzzy
msgid ""
"Performs a cubic interpolation between this vector and [code]b[/code] using "
"[code]pre_a[/code] and [code]post_b[/code] as handles, and returns the "
"result at position [code]weight[/code]. [code]weight[/code] is on the range "
"of 0.0 to 1.0, representing the amount of interpolation."
msgstr ""
-"用[code]pre_a[/code]å’Œ[code]post_b[/code]ä½œä¸ºå¥æŸ„,在这个å‘é‡å’Œ[code]b[/code]"
-"之间进行三次æ’值,并在[code]weight[/code]ä½ç½®è¿”回结果。[code]weight[/code]çš„"
-"范围是0.0到1.0,表示æ’值的é‡ã€‚"
+"用 [code]pre_a[/code] å’Œ [code]post_b[/code] ä½œä¸ºå¥æŸ„,在这个å‘é‡å’Œ [code]b[/"
+"code] 之间进行三次æ’值,并在 [code]weight[/code] ä½ç½®è¿”回结果。[code]weight[/"
+"code] 的范围是 0.0 到 1.0,表示æ’值的é‡ã€‚"
#: doc/classes/Vector3.xml
msgid "Returns the distance between this vector and [code]b[/code]."
@@ -77909,7 +78380,6 @@ msgid ""
msgstr "如果[code]true[/code],视窗上的GUI控件将完美地放置åƒç´ ã€‚"
#: doc/classes/Viewport.xml
-#, fuzzy
msgid ""
"If [code]true[/code], the viewport rendering will receive benefits from High "
"Dynamic Range algorithm. High Dynamic Range allows the viewport to receive "
@@ -77920,11 +78390,12 @@ msgid ""
"[constant USAGE_3D_NO_EFFECTS], since HDR is not supported for 2D.\n"
"[b]Note:[/b] Only available on the GLES3 backend."
msgstr ""
-"如果[code]true[/code],视窗的渲染将获得高动æ€èŒƒå›´ç®—法的收益。高动æ€èŒƒå›´å…许视"
-"窗接收0-1范围以外的数值。在Godot中HDR使用16比特,这æ„味ç€å®ƒä¸èƒ½å­˜å‚¨æµ®ç‚¹æ•°çš„å…¨"
-"部范围。\n"
-"[b]注æ„:[/b] 需è¦å°† [member usage]设置为[constant USAGE_3D]或[constant "
-"USAGE_3D_NO_EFFECTS],2D䏿”¯æŒHDR。"
+"如果为 [code]true[/code],视窗的渲染将获益于高动æ€èŒƒå›´ç®—法。高动æ€èŒƒå›´å…许视"
+"窗接收 0-1 范围以外的数值。在 Godot 中 HDR 默认使用åŠç²¾åº¦æµ®ç‚¹æ•°ï¼ˆ16 ä½ï¼‰ã€‚è¦"
+"使用全精度浮点数(32 ä½ï¼‰ï¼Œè¯·å¯ç”¨ [member use_32_bpc_depth]。\n"
+"[b]注æ„:[/b]需è¦å°† [member usage] 设置为 [constant USAGE_3D] 或 [constant "
+"USAGE_3D_NO_EFFECTS],因为 HDR 䏿”¯æŒ 2D。\n"
+"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸­å¯ç”¨ã€‚"
#: doc/classes/Viewport.xml
msgid ""
@@ -78074,6 +78545,12 @@ msgid ""
"enable [member debanding] instead.\n"
"[b]Note:[/b] Only available on the GLES3 backend."
msgstr ""
+"如果为 [code]true[/code],分é…该视窗的帧缓冲时将使用完整浮点数精度(32 ä½ï¼‰è€Œ"
+"䏿˜¯åŠæµ®ç‚¹æ•°ç²¾åº¦ï¼ˆ16 ä½ï¼‰ã€‚ä»…åœ¨åŒæ—¶å¯ç”¨ [member hdr] 时有效。\n"
+"[b]注æ„:[/b]å¯ç”¨è¿™ä¸ªè®¾ç½®ä¸ä¼šæå‡æ¸²æŸ“è´¨é‡ã€‚ä½¿ç”¨å®Œæ•´æµ®ç‚¹æ•°ç²¾åº¦è¾ƒæ…¢ï¼Œä¸€èˆ¬åªæœ‰è¦"
+"求更高精度的高级ç€è‰²å™¨éœ€è¦ä½¿ç”¨ã€‚如果是è¦å‡å°‘æ¡å¸¦æ•ˆåº”,请å¯ç”¨ [member "
+"debanding]。\n"
+"[b]注æ„:[/b]仅在 GLES3 åŽç«¯ä¸­å¯ç”¨ã€‚"
#: doc/classes/Viewport.xml
msgid "The custom [World] which can be used as 3D environment source."
@@ -78189,7 +78666,7 @@ msgstr "表示 [enum RenderInfo] 枚举的大å°ã€‚"
#: doc/classes/Viewport.xml
msgid "Objects are displayed normally."
-msgstr "对象显示正常。"
+msgstr "对象正常显示。"
#: doc/classes/Viewport.xml
msgid "Objects are displayed without light information."
@@ -78664,7 +79141,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "A script implemented in the Visual Script programming environment."
-msgstr "一个在å¯è§†åŒ–脚本编程环境中实现的脚本。"
+msgstr "在 Visual Script 编程环境中实现的脚本。"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid ""
@@ -78682,36 +79159,35 @@ msgstr ""
"您最有å¯èƒ½é€šè¿‡ Visual Script 编辑器或在为其编写æ’件时使用此类。"
#: modules/visual_script/doc_classes/VisualScript.xml
-#, fuzzy
msgid "$DOCS_URL/tutorials/scripting/visual_script/index.html"
-msgstr "$DOCS_URL/getting_started/scripting/visual_script/index.html"
+msgstr "$DOCS_URL/tutorials/scripting/visual_script/index.html"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Add a custom signal with the specified name to the VisualScript."
-msgstr "在å¯è§†åŒ–脚本中添加指定å称的自定义信å·ã€‚"
+msgstr "在 VisualScript 中添加指定å称的自定义信å·ã€‚"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Add a function with the specified name to the VisualScript."
-msgstr "在å¯è§†åŒ–脚本中添加指定å称的函数。"
+msgstr "在 VisualScript 中添加指定å称的函数。"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Add a node to a function of the VisualScript."
-msgstr "å‘å¯è§†åŒ–脚本的函数添加节点。"
+msgstr "å‘ VisualScript 的函数添加节点。"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid ""
"Add a variable to the VisualScript, optionally giving it a default value or "
"marking it as exported."
-msgstr "在å¯è§†åŒ–脚本中添加一个å˜é‡ï¼Œå¯é€‰æ‹©ç»™å®ƒä¸€ä¸ªé»˜è®¤å€¼æˆ–将其标记为导出。"
+msgstr "在 VisualScript 中添加一个å˜é‡ï¼Œå¯é€‰æ‹©ç»™å®ƒä¸€ä¸ªé»˜è®¤å€¼æˆ–将其标记为导出。"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid ""
"Add an argument to a custom signal added with [method add_custom_signal]."
-msgstr "为用[method add_custom_signal]æ·»åŠ çš„è‡ªå®šä¹‰ä¿¡å·æ·»åŠ ä¸€ä¸ªå‚æ•°ã€‚"
+msgstr "为用 [method add_custom_signal] æ·»åŠ çš„è‡ªå®šä¹‰ä¿¡å·æ·»åŠ ä¸€ä¸ªå‚æ•°ã€‚"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Get the count of a custom signal's arguments."
-msgstr "获å–自定义信å·çš„傿•°è®¡æ•°ã€‚"
+msgstr "获å–自定义信å·çš„傿•°ä¸ªæ•°ã€‚"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Get the name of a custom signal's argument."
@@ -78753,7 +79229,7 @@ msgstr "断开之å‰ç”¨[method data_connect]连接的两个数æ®ç«¯å£ã€‚"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Returns the id of a function's entry point node."
-msgstr "返回函数入å£ç‚¹èŠ‚ç‚¹çš„ID。"
+msgstr "返回函数入å£ç‚¹èŠ‚ç‚¹çš„ ID。"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Returns the position of the center of the screen for a given function."
@@ -78850,7 +79326,7 @@ msgstr ""
msgid ""
"Disconnect two sequence ports previously connected with [method "
"sequence_connect]."
-msgstr "断开之å‰ç”¨[method sequence_connect]连接的两个åºåˆ—端å£ã€‚"
+msgstr "断开之å‰ç”¨ [method sequence_connect] 连接的两个åºåˆ—端å£ã€‚"
#: modules/visual_script/doc_classes/VisualScript.xml
msgid "Position the center of the screen for a function."
@@ -78883,13 +79359,13 @@ msgstr "å½“èŠ‚ç‚¹ç«¯å£æ›´æ”¹æ—¶è§¦å‘。"
#: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
msgid "A Visual Script node representing a constant from the base types."
-msgstr "一个å¯è§†åŒ–脚本节点,表示基本类型中的一个常é‡ã€‚"
+msgstr "一个 Visual Script 节点,表示基本类型中的一个常é‡ã€‚"
#: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
msgid ""
"A Visual Script node representing a constant from base types, such as "
"[constant Vector3.AXIS_X]."
-msgstr "表示基本类型常é‡çš„å¯è§†åŒ–脚本节点,如[constant Vector3.AXIS_X]。"
+msgstr "表示基本类型常é‡çš„ Visual Script 节点,如 [constant Vector3.AXIS_X]。"
#: modules/visual_script/doc_classes/VisualScriptBasicTypeConstant.xml
msgid "The type to get the constant from."
@@ -78901,7 +79377,7 @@ msgstr "è¦è¿”回的常é‡çš„å称。"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid "A Visual Script node used to call built-in functions."
-msgstr "用于调用内置函数的å¯è§†åŒ–脚本节点。"
+msgstr "用于调用内置函数的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid ""
@@ -79123,7 +79599,7 @@ msgstr "将输入从分è´éŸ³é‡è½¬æ¢ä¸ºçº¿æ€§éŸ³é‡ã€‚"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid "Return the greater of the two numbers, also known as their maximum."
-msgstr "返回两个数字中较大的一个,也称为它们的最大值。"
+msgstr "返回两个数字中较大的一个,也被称为它们的最大值。"
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid "Return the lesser of the two numbers, also known as their minimum."
@@ -79234,7 +79710,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
msgid "Represents the size of the [enum BuiltinFunc] enum."
-msgstr "表示[enum BuiltinFunc]枚举的大å°ã€‚"
+msgstr "表示 [enum BuiltinFunc] 枚举的大å°ã€‚"
#: modules/visual_script/doc_classes/VisualScriptClassConstant.xml
msgid "Gets a constant from a given class."
@@ -79249,12 +79725,12 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (variant): [code]value[/code]"
msgstr ""
-"该节点从指定类中返回常é‡ï¼Œä¾‹å¦‚[constant TYPE_INT]。关于å¯ç”¨çš„常é‡ï¼Œè¯·å‚阅指定"
-"类的文档。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]value[/code]"
+"该节点从指定类中返回常é‡ï¼Œä¾‹å¦‚ [constant TYPE_INT]。关于å¯ç”¨çš„常é‡ï¼Œè¯·å‚阅指"
+"定类的文档。\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]value[/code]"
#: modules/visual_script/doc_classes/VisualScriptClassConstant.xml
msgid "The constant's parent class."
@@ -79267,7 +79743,7 @@ msgstr "è¦è¿”回的常é‡ã€‚å¯ç”¨çš„常é‡å‚阅给定的类。"
#: modules/visual_script/doc_classes/VisualScriptComment.xml
msgid "A Visual Script node used to annotate the script."
-msgstr "用于注释脚本的å¯è§†åŒ–脚本节点。"
+msgstr "用于注释脚本的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptComment.xml
msgid ""
@@ -79275,7 +79751,7 @@ msgid ""
"may be documented.\n"
"Comment nodes can be resized so they encompass a group of nodes."
msgstr ""
-"å¯è§†åŒ–脚本节点,用于显示脚本中的注释,以便记录代ç ã€‚\n"
+"Visual Script èŠ‚ç‚¹ï¼Œç”¨äºŽæ˜¾ç¤ºè„šæœ¬ä¸­çš„æ³¨é‡Šï¼Œä»¥ä¾¿ä¸ºä»£ç æä¾›æ–‡æ¡£ã€‚\n"
"注释节点å¯ä»¥è°ƒæ•´å¤§å°ï¼Œä»¥ä¾¿åŒ…å«ä¸€ç»„节点。"
#: modules/visual_script/doc_classes/VisualScriptComment.xml
@@ -79292,19 +79768,19 @@ msgstr "注释节点的标题。"
#: modules/visual_script/doc_classes/VisualScriptComposeArray.xml
msgid "A Visual Script Node used to create array from a list of items."
-msgstr "å¯è§†åŒ–脚本节点,用于从项目列表中创建数组。"
+msgstr "Visual Script 节点,用于从项目列表中创建数组。"
#: modules/visual_script/doc_classes/VisualScriptComposeArray.xml
msgid ""
"A Visual Script Node used to compose array from the list of elements "
"provided with custom in-graph UI hard coded in the VisualScript Editor."
msgstr ""
-"å¯è§†åŒ–脚本节点,用于从å¯è§†åŒ–脚本编辑器中硬编ç çš„自定义图åƒå†…ç”¨æˆ·ç•Œé¢æä¾›çš„å…ƒ"
-"ç´ åˆ—è¡¨ä¸­ç»„æˆæ•°ç»„。"
+"Visual Script 节点,用于从å¯è§†åŒ–脚本编辑器中硬编ç çš„自定义图åƒå†…ç”¨æˆ·ç•Œé¢æä¾›"
+"çš„å…ƒç´ åˆ—è¡¨ä¸­ç»„æˆæ•°ç»„。"
#: modules/visual_script/doc_classes/VisualScriptCondition.xml
msgid "A Visual Script node which branches the flow."
-msgstr "å¯è§†åŒ–脚本节点,它是æµç¨‹çš„分支。"
+msgstr "Visual Script 节点,它是æµç¨‹çš„分支。"
#: modules/visual_script/doc_classes/VisualScriptCondition.xml
msgid ""
@@ -79320,16 +79796,16 @@ msgid ""
"- Sequence: [code]false[/code]\n"
"- Sequence: [code]done[/code]"
msgstr ""
-"å¯è§†åŒ–脚本节点,检查一个[bool]输入端å£ã€‚如果[code]true[/code],它将通过 "
-"\"true\" åºåˆ—端å£é€€å‡ºã€‚如果[code]false[/code],它将通过 \"false\" åºåˆ—端å£é€€"
-"å‡ºã€‚åœ¨é€€å‡ºè¿™ä¸¤ç§æƒ…况åŽï¼Œå®ƒé€šè¿‡ \"done\" 端å£é€€å‡ºã€‚åºåˆ—端å£å¯ä»¥ä¸è¿žæŽ¥ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]if (cond) is[/code]\n"
-"- Data (boolean): [code]cond[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence: [code]true[/code]\n"
-"- Sequence: [code]false[/code]\n"
-"- Sequence: [code]done[/code]"
+"Visual Script 节点,检查 [bool] 输入端å£ã€‚如果为 [code]true[/code],它将通"
+"过“trueâ€åºåˆ—端å£é€€å‡ºã€‚如果为 [code]false[/code],它将通过“falseâ€åºåˆ—端å£é€€"
+"å‡ºã€‚åœ¨é€€å‡ºè¿™ä¸¤ç§æƒ…况åŽï¼Œå®ƒé€šè¿‡â€œdoneâ€ç«¯å£é€€å‡ºã€‚åºåˆ—端å£å¯ä»¥ä¸è¿žæŽ¥ã€‚\n"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]if (cond) is[/code]\n"
+"- æ•°æ®ï¼ˆå¸ƒå°”):[code]cond[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]true[/code]\n"
+"- åºåˆ—:[code]false[/code]\n"
+"- åºåˆ—:[code]done[/code]"
#: modules/visual_script/doc_classes/VisualScriptConstant.xml
msgid "Gets a contant's value."
@@ -79344,10 +79820,10 @@ msgid ""
"- Data (variant): [code]get[/code]"
msgstr ""
"该节点返回常é‡çš„值。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]get[/code]"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]"
#: modules/visual_script/doc_classes/VisualScriptConstant.xml
msgid "The constant's type."
@@ -79359,21 +79835,21 @@ msgstr "常é‡çš„值。"
#: modules/visual_script/doc_classes/VisualScriptConstructor.xml
msgid "A Visual Script node which calls a base type constructor."
-msgstr "å¯è§†åŒ–脚本节点,调用一个基本类型的构造函数。"
+msgstr "Visual Script 节点,调用一个基本类型的构造函数。"
#: modules/visual_script/doc_classes/VisualScriptConstructor.xml
msgid ""
"A Visual Script node which calls a base type constructor. It can be used for "
"type conversion as well."
-msgstr "å¯è§†åŒ–脚本节点,调用一个基本类型的构造函数。它也å¯ä»¥ç”¨äºŽç±»åž‹è½¬æ¢ã€‚"
+msgstr "Visual Script 节点,调用一个基本类型的构造函数。它也å¯ä»¥ç”¨äºŽç±»åž‹è½¬æ¢ã€‚"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "A scripted Visual Script node."
-msgstr "有脚本的å¯è§†åŒ–脚本节点。"
+msgstr "有脚本的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "A custom Visual Script node which can be scripted in powerful ways."
-msgstr "自定义的å¯è§†åŒ–脚本节点,å¯ä»¥ç”¨å¼ºå¤§çš„æ–¹å¼è¿›è¡Œè„šæœ¬ç¼–å†™ã€‚"
+msgstr "自定义的 Visual Script 节点,å¯ä»¥ç”¨å¼ºå¤§çš„æ–¹å¼è¿›è¡Œè„šæœ¬ç¼–å†™ã€‚"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "Return the node's title."
@@ -79408,11 +79884,11 @@ msgstr "返回指定输入端å£çš„类型。å‚阅[enum Variant.Type]值。"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "Return the amount of output [b]sequence[/b] ports."
-msgstr "返回输出[b]sequence[/b]åºåˆ—端å£çš„æ•°é‡ã€‚"
+msgstr "返回输出[b]åºåˆ—[/b]端å£çš„æ•°é‡ã€‚"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "Return the specified [b]sequence[/b] output's name."
-msgstr "返回指定的[b]sequence[/b]åºåˆ—输出的å称。"
+msgstr "返回指定的[b]åºåˆ—[/b]输出的å称。"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "Return the amount of output value ports."
@@ -79443,8 +79919,8 @@ msgid ""
"[b]sequence[/b] port (if there is none, on the place that is usually taken "
"by it)."
msgstr ""
-"返回自定义节点的文本,就在输入[b]sequence[/b]åºåˆ—ç«¯å£æ—边显示,如果没有,则在"
-"通常被它å ç”¨çš„ä½ç½®ã€‚"
+"返回自定义节点的文本,就在输入[b]åºåˆ—[/b]ç«¯å£æ—边显示,如果没有,则在通常被它"
+"å ç”¨çš„ä½ç½®ã€‚"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid ""
@@ -79454,7 +79930,7 @@ msgstr "返回自定义节点的è¿è¡Œå†…存的大å°ã€‚更多细节å‚阅 [meth
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid "Return whether the custom node has an input [b]sequence[/b] port."
-msgstr "è¿”å›žè‡ªå®šä¹‰èŠ‚ç‚¹æ˜¯å¦æœ‰è¾“å…¥[b]sequence[/b]åºåˆ—端å£ã€‚"
+msgstr "è¿”å›žè‡ªå®šä¹‰èŠ‚ç‚¹æ˜¯å¦æœ‰è¾“å…¥[b]åºåˆ—[/b]端å£ã€‚"
#: modules/visual_script/doc_classes/VisualScriptCustomNode.xml
msgid ""
@@ -79536,7 +80012,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml
msgid ""
"A Visual Script node which deconstructs a base type instance into its parts."
-msgstr "å¯è§†åŒ–脚本节点,它将一个基本类型的实例解构为其å„个部分。"
+msgstr "Visual Script 节点,它将一个基本类型的实例解构为其å„个部分。"
#: modules/visual_script/doc_classes/VisualScriptDeconstruct.xml
msgid "The type to deconstruct."
@@ -79547,20 +80023,20 @@ msgid ""
"Add a custom Visual Script node to the editor. It'll be placed under "
"\"Custom Nodes\" with the [code]category[/code] as the parameter."
msgstr ""
-"在编辑器中添加自定义å¯è§†åŒ–脚本节点。它放在 \"自定义节点\" 下,以"
-"[code]category[/code]ä½œä¸ºå‚æ•°ã€‚"
+"在编辑器中添加自定义 Visual Script 节点。它放在“自定义节点â€ä¸‹ï¼Œä»¥ "
+"[code]category[/code] ä½œä¸ºå‚æ•°ã€‚"
#: modules/visual_script/doc_classes/VisualScriptEditor.xml
msgid ""
"Remove a custom Visual Script node from the editor. Custom nodes already "
"placed on scripts won't be removed."
msgstr ""
-"从编辑器中删除一个自定义å¯è§†åŒ–è„šæœ¬èŠ‚ç‚¹ã€‚å·²ç»æ”¾åœ¨è„šæœ¬ä¸Šçš„è‡ªå®šä¹‰èŠ‚ç‚¹ä¸ä¼šè¢«åˆ "
-"除。"
+"从编辑器中删除一个自定义 Visual Script èŠ‚ç‚¹ã€‚å·²ç»æ”¾åœ¨è„šæœ¬ä¸Šçš„è‡ªå®šä¹‰èŠ‚ç‚¹ä¸ä¼šè¢«"
+"删除。"
#: modules/visual_script/doc_classes/VisualScriptEditor.xml
msgid "Emitted when a custom Visual Script node is added or removed."
-msgstr "当添加或删除一个自定义å¯è§†åŒ–脚本节点时触å‘。"
+msgstr "当添加或删除一个自定义 Visual Script 节点时触å‘。"
#: modules/visual_script/doc_classes/VisualScriptEmitSignal.xml
msgid "Emits a specified signal."
@@ -79575,10 +80051,10 @@ msgid ""
"- Sequence"
msgstr ""
"当它被执行时å‘出一个指定的信å·ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]emit[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]emit[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—"
#: modules/visual_script/doc_classes/VisualScriptEmitSignal.xml
msgid "The signal to emit."
@@ -79586,7 +80062,7 @@ msgstr "触å‘的信å·ã€‚"
#: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml
msgid "A Visual Script node returning a singleton from [@GlobalScope]."
-msgstr "从 [@GlobalScope] 返回å•例的å¯è§†åŒ–脚本节点。"
+msgstr "从 [@GlobalScope] 返回å•例的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptEngineSingleton.xml
msgid "The singleton's name."
@@ -79594,7 +80070,7 @@ msgstr "å•例的å称。"
#: modules/visual_script/doc_classes/VisualScriptExpression.xml
msgid "A Visual Script node that can execute a custom expression."
-msgstr "å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„å¯è§†åŒ–脚本节点。"
+msgstr "å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„ Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptExpression.xml
msgid ""
@@ -79602,12 +80078,12 @@ msgid ""
"provided for the input and the expression result can be retrieved from the "
"output."
msgstr ""
-"å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„å¯è§†åŒ–脚本节点。å¯ä»¥ä¸ºè¾“å…¥æä¾›å€¼ï¼Œå¹¶ä¸”å¯ä»¥ä»Žè¾“出中检索"
-"表达å¼ç»“果。"
+"å¯ä»¥æ‰§è¡Œè‡ªå®šä¹‰è¡¨è¾¾å¼çš„ Visual Script 节点。å¯ä»¥ä¸ºè¾“å…¥æä¾›å€¼ï¼Œå¹¶ä¸”å¯ä»¥ä»Žè¾“出中"
+"检索表达å¼ç»“果。"
#: modules/visual_script/doc_classes/VisualScriptFunction.xml
msgid "A Visual Script node representing a function."
-msgstr "一个Visual Script节点,表示一个函数。"
+msgstr "表示函数的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptFunction.xml
msgid ""
@@ -79620,7 +80096,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
msgid "A Visual Script node for calling a function."
-msgstr "用于调用函数的å¯è§†åŒ–脚本节点。"
+msgstr "用于调用函数的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptFunctionCall.xml
msgid ""
@@ -79748,7 +80224,7 @@ msgstr "该方法将被远程调用,用于给定的对等体,使用一个ä¸
#: modules/visual_script/doc_classes/VisualScriptFunctionState.xml
msgid "A Visual Script node representing a function state."
-msgstr "一个Visual Script节点,表示函数状æ€ã€‚"
+msgstr "表示函数状æ€çš„ Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptFunctionState.xml
msgid ""
@@ -79784,7 +80260,7 @@ msgstr "è¦ä½¿ç”¨çš„常é‡ã€‚"
#: modules/visual_script/doc_classes/VisualScriptIndexGet.xml
msgid "A Visual Script node for getting a value from an array or a dictionary."
-msgstr "一个Visual Script节点,用于从数组或字典中获å–值。"
+msgstr "用于从数组或字典中å–值的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptIndexGet.xml
msgid ""
@@ -79794,7 +80270,7 @@ msgstr "[VisualScriptIndexGet]将返回存储在指定索引下的数组或字å…
#: modules/visual_script/doc_classes/VisualScriptIndexSet.xml
msgid "A Visual Script node for setting a value in an array or a dictionary."
-msgstr "一个Visual Script节点,用于设置数组或字典中的值。"
+msgstr "ç”¨äºŽå‘æ•°ç»„或字典中设值的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptIndexSet.xml
msgid ""
@@ -79805,7 +80281,7 @@ msgstr ""
#: modules/visual_script/doc_classes/VisualScriptInputAction.xml
msgid "A Visual Script node returning a state of an action."
-msgstr "返回动作状æ€çš„å¯è§†åŒ–脚本节点。"
+msgstr "返回动作状æ€çš„ Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptInputAction.xml
msgid ""
@@ -79856,17 +80332,17 @@ msgid ""
msgstr ""
"这个节点在给定的输入中é€é¡¹è¿›è¡Œã€‚输入å¯ä»¥æ˜¯ä»»ä½•åºåˆ—æ•°æ®ç±»åž‹ï¼Œå¦‚[Array]或"
"[String]。当æ¯ä¸ªé¡¹è¢«å¤„ç†å®ŒåŽï¼Œæ‰§è¡Œä¼ å‡º[code]exit[/code] åºåˆ—端å£ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]for (elem) in (input)[/code]\n"
-"- Data (variant): [code]input[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence: [code]each[/code]\n"
-"- Sequence: [code]exit[/code]\n"
-"- Data (variant): [code]elem[/code]"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]for (elem) in (input)[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]input[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]each[/code]\n"
+"- åºåˆ—:[code]exit[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]elem[/code]"
#: modules/visual_script/doc_classes/VisualScriptLists.xml
msgid "A Visual Script virtual class for in-graph editable nodes."
-msgstr "图内å¯ç¼–辑节点的å¯è§†åŒ–脚本虚拟类。"
+msgstr "图内å¯ç¼–辑节点的 Visual Script 虚类。"
#: modules/visual_script/doc_classes/VisualScriptLists.xml
msgid ""
@@ -79920,11 +80396,11 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (variant): [code]get[/code]"
msgstr ""
-"返回局部å˜é‡çš„值。必须æä¾› \"Var Name\",并æä¾›å¯é€‰ç±»åž‹ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]get[/code]"
+"返回局部å˜é‡çš„值。必须æä¾›å˜é‡å称“Var Nameâ€ï¼Œå¹¶æä¾›å¯é€‰ç±»åž‹ã€‚\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]"
#: modules/visual_script/doc_classes/VisualScriptLocalVar.xml
#: modules/visual_script/doc_classes/VisualScriptLocalVarSet.xml
@@ -79952,12 +80428,12 @@ msgid ""
"- Data (variant): [code]get[/code]"
msgstr ""
"将一个局部å˜é‡çš„值更改为给定的输入值。新的值也会在输出端æä¾›æ•°æ®ç«¯å£ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence\n"
-"- Data (variant): [code]set[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence\n"
-"- Data (variant): [code]get[/code]"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]set[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]"
#: modules/visual_script/doc_classes/VisualScriptMathConstant.xml
msgid "Commonly used mathematical constants."
@@ -79971,11 +80447,11 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (variant): [code]get[/code]"
msgstr ""
-"在输出数æ®ç«¯å£ä¸Šæä¾›å¸¸è§çš„æ•°å­¦å¸¸é‡ï¼Œå¦‚Pi等。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]get[/code]"
+"在输出数æ®ç«¯å£ä¸Šæä¾› Pi 等常è§çš„æ•°å­¦å¸¸é‡ã€‚\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]get[/code]"
#: modules/visual_script/doc_classes/VisualScriptMathConstant.xml
msgid "The math constant."
@@ -80039,7 +80515,7 @@ msgstr "返回给定端å£çš„默认值。当没有任何东西连接到该端å£
#: modules/visual_script/doc_classes/VisualScriptNode.xml
msgid "Returns the [VisualScript] instance the node is bound to."
-msgstr "返回该节点所绑定的[VisualScript]实例。"
+msgstr "返回该节点所绑定的 [VisualScript] 实例。"
#: modules/visual_script/doc_classes/VisualScriptNode.xml
msgid ""
@@ -80068,10 +80544,10 @@ msgid ""
"- Data (variant): [code]result[/code]"
msgstr ""
"[b]输入端å£ï¼š[/b]\n"
-"- æ•°æ®ï¼ˆvariant):[code]A[/code]\n"
-"- æ•°æ®ï¼ˆvariant):[code]B[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]A[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]B[/code]\n"
"[b]输出端å£ï¼š[/b]\n"
-"- æ•°æ®ï¼ˆvariant):[code]result[/code]"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]result[/code]"
#: modules/visual_script/doc_classes/VisualScriptOperator.xml
msgid ""
@@ -80097,11 +80573,11 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (object): [code]res[/code]"
msgstr ""
-"创建新的[Resource]或从文件系统加载一个。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (object): [code]res[/code]"
+"创建新的 [Resource] 或从文件系统加载。\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå¯¹è±¡ï¼‰ï¼š[code]res[/code]"
#: modules/visual_script/doc_classes/VisualScriptPreload.xml
msgid "The [Resource] to load."
@@ -80191,7 +80667,7 @@ msgstr "该属性将从 GDScript 基本类型中检索,例如 [Vector2]。"
#: modules/visual_script/doc_classes/VisualScriptPropertySet.xml
msgid "A Visual Script node that sets a property of an [Object]."
-msgstr "一个Visual Script节点,用于设置[Object]的属性。"
+msgstr "用于设置对象 [Object] 的属性的 Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptPropertySet.xml
msgid ""
@@ -80320,15 +80796,15 @@ msgid ""
msgstr ""
"结æŸä¸€ä¸ªå‡½æ•°çš„æ‰§è¡Œå¹¶å°†æŽ§åˆ¶æƒè¿”回给调用函数。å¯é€‰ï¼Œå®ƒå¯ä»¥è¿”回一个[Variant]"
"值。\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence\n"
-"- Data (variant): [code]result[/code] (optional)\n"
-"[b]Output Ports:[/b]\n"
-"none"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]result[/code](å¯é€‰ï¼‰\n"
+"[b]输出端å£ï¼š[/b]\n"
+"æ— "
#: modules/visual_script/doc_classes/VisualScriptReturn.xml
msgid "If [code]true[/code], the [code]return[/code] input port is available."
-msgstr "如果[code]true[/code],则[code]return[/code]输入端å£å¯ç”¨ã€‚"
+msgstr "如果为 [code]true[/code],则 [code]return[/code] 输入端å£å¯ç”¨ã€‚"
#: modules/visual_script/doc_classes/VisualScriptReturn.xml
msgid "The return value's data type."
@@ -80347,10 +80823,10 @@ msgid ""
"- Data: [code]node[/code] (obj)"
msgstr ""
"对节点的直接引用。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data: [code]node[/code] (obj)"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼š[code]node[/code](obj)"
#: modules/visual_script/doc_classes/VisualScriptSceneNode.xml
msgid "The node's path in the scene tree."
@@ -80375,12 +80851,12 @@ msgid ""
"- Data (variant): [code]out[/code]"
msgstr ""
"æ ¹æ®ä¸€ä¸ªå¸ƒå°”æ¡ä»¶åœ¨ä¸¤ä¸ªè¾“入值之间进行选择。\n"
-"[b]Input Ports:[/b]\n"
+"[b]输入端å£ï¼š[/b]\n"
"- Data (boolean): [code]cond[/code]\n"
-"- Data (variant): [code]a[/code]\n"
-"- Data (variant): [code]b[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]out[/code]"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]a[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]b[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]out[/code]"
#: modules/visual_script/doc_classes/VisualScriptSelect.xml
msgid "The input variables' type."
@@ -80398,11 +80874,11 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (object): [code]instance[/code]"
msgstr ""
-"æä¾›å¯¹è¿è¡Œå¯è§†åŒ–脚本的节点的引用。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (object): [code]instance[/code]"
+"æä¾›å¯¹è¿è¡Œ Visual Script 的节点的引用。\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå¯¹è±¡ï¼‰ï¼š[code]instance[/code]"
#: modules/visual_script/doc_classes/VisualScriptSequence.xml
msgid "Executes a series of Sequence ports."
@@ -80421,11 +80897,11 @@ msgid ""
msgstr ""
"通过一系列的一个或多个输出åºåˆ—端å£è¿›è¡Œæ­¥è¿›ã€‚[code]current[/code]当剿•°æ®ç«¯å£"
"è¾“å‡ºå½“å‰æ‰§è¡Œçš„项。\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]in order[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence: [code]1[/code]\n"
-"- Sequence: [code]2 - n[/code] (optional)\n"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]in order[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]1[/code]\n"
+"- åºåˆ—:[code]2 - n[/code] (optional)\n"
"- Data (int): [code]current[/code]"
#: modules/visual_script/doc_classes/VisualScriptSequence.xml
@@ -80470,19 +80946,19 @@ msgid ""
msgstr ""
"æ ¹æ®è¾“入值æ¥åˆ†æ”¯æµç¨‹ã€‚在属性检查器中使用[b]Case Count[/b]æ¥è®¾ç½®åˆ†æ”¯çš„æ•°é‡å’Œæ¯"
"个比较的å¯é€‰ç±»åž‹ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]'input' is[/code]\n"
-"- Data (variant): [code]=[/code]\n"
-"- Data (variant): [code]=[/code] (optional)\n"
-"- Data (variant): [code]input[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence\n"
-"- Sequence (optional)\n"
-"- Sequence: [code]done[/code]"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]'input' is[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]=[/code]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]=[/code](å¯é€‰ï¼‰\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]input[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—\n"
+"- åºåˆ—(å¯é€‰ï¼‰\n"
+"- åºåˆ—:[code]done[/code]"
#: modules/visual_script/doc_classes/VisualScriptTypeCast.xml
msgid "A Visual Script node that casts the given value to another type."
-msgstr "一个Visual Script节点,将给定的值转æ¢ä¸ºå¦ä¸€ç§ç±»åž‹ã€‚"
+msgstr "将给定的值转æ¢ä¸ºå¦ä¸€ç§ç±»åž‹çš„ Visual Script 节点。"
#: modules/visual_script/doc_classes/VisualScriptTypeCast.xml
msgid ""
@@ -80513,11 +80989,11 @@ msgid ""
"[b]Output Ports:[/b]\n"
"- Data (variant): [code]value[/code]"
msgstr ""
-"返回å˜é‡çš„值。必须æä¾› \"Var Name\",并有一个å¯é€‰çš„类型。\n"
-"[b]Input Ports:[/b]\n"
-"none\n"
-"[b]Output Ports:[/b]\n"
-"- Data (variant): [code]value[/code]"
+"返回å˜é‡çš„值。必须æä¾›å˜é‡å称“Var Nameâ€ï¼Œå¹¶æœ‰ä¸€ä¸ªå¯é€‰çš„类型。\n"
+"[b]输入端å£ï¼š[/b]\n"
+"æ— \n"
+"[b]输出端å£ï¼š[/b]\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]value[/code]"
#: modules/visual_script/doc_classes/VisualScriptVariableGet.xml
#: modules/visual_script/doc_classes/VisualScriptVariableSet.xml
@@ -80538,11 +81014,11 @@ msgid ""
"- Sequence"
msgstr ""
"å°†å˜é‡çš„值更改为给定的输入。\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence\n"
-"- Data (variant): [code]set[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—\n"
+"- æ•°æ®ï¼ˆå˜ä½“):[code]set[/code]\n"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—"
#: modules/visual_script/doc_classes/VisualScriptWhile.xml
msgid "Conditional loop."
@@ -80561,12 +81037,12 @@ msgid ""
msgstr ""
"当一个æ¡ä»¶ä¸º[code]true[/code]æ—¶è¿›è¡Œå¾ªçŽ¯ã€‚å½“å¾ªçŽ¯ç»“æŸæ—¶ï¼Œæ‰§è¡Œç»§ç»­ä»Ž[code]exit[/"
"code]åºåˆ—端å£å‡ºæ¥ã€‚\n"
-"[b]Input Ports:[/b]\n"
-"- Sequence: [code]while(cond)[/code]\n"
+"[b]输入端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]while(cond)[/code]\n"
"- Data (bool): [code]cond[/code]\n"
-"[b]Output Ports:[/b]\n"
-"- Sequence: [code]repeat[/code]\n"
-"- Sequence: [code]exit[/code]"
+"[b]输出端å£ï¼š[/b]\n"
+"- åºåˆ—:[code]repeat[/code]\n"
+"- åºåˆ—:[code]exit[/code]"
#: modules/visual_script/doc_classes/VisualScriptYield.xml
msgid "A Visual Script node used to pause a function execution."
@@ -83189,7 +83665,7 @@ msgstr "设置应更新视窗的时间。请å‚阅 [enum ViewportUpdateMode] 。
msgid ""
"Sets the viewport's 2D/3D mode. See [enum ViewportUsage] constants for "
"options."
-msgstr "设置视窗的2D/3D模å¼ã€‚选项è§[enum ViewportUsage]视窗使用常数。"
+msgstr "设置视窗的 2D/3D 模å¼ã€‚é€‰é¡¹è§ [enum ViewportUsage] 常é‡ã€‚"
#: doc/classes/VisualServer.xml
msgid ""
@@ -83346,39 +83822,39 @@ msgstr ""
#: doc/classes/VisualServer.xml
msgid "Shader is a 3D shader."
-msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ª 3D ç€è‰²å™¨ã€‚"
+msgstr "ç€è‰²å™¨æ˜¯ 3D ç€è‰²å™¨ã€‚"
#: doc/classes/VisualServer.xml
msgid "Shader is a 2D shader."
-msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ª 2D ç€è‰²å™¨ã€‚"
+msgstr "ç€è‰²å™¨æ˜¯ 2D ç€è‰²å™¨ã€‚"
#: doc/classes/VisualServer.xml
msgid "Shader is a particle shader."
-msgstr "ç€è‰²å™¨æ˜¯ä¸€ä¸ªç²’å­ç€è‰²å™¨ã€‚"
+msgstr "ç€è‰²å™¨æ˜¯ç²’å­ç€è‰²å™¨ã€‚"
#: doc/classes/VisualServer.xml
msgid "Represents the size of the [enum ShaderMode] enum."
-msgstr "代表[enum ShaderMode]枚举的大å°ã€‚"
+msgstr "代表 [enum ShaderMode] 枚举的大å°ã€‚"
#: doc/classes/VisualServer.xml
msgid "Array is a vertex array."
-msgstr "数组是一个顶点数组。"
+msgstr "数组是顶点数组。"
#: doc/classes/VisualServer.xml
msgid "Array is a normal array."
-msgstr "数组是普通数组。"
+msgstr "数组是法线数组。"
#: doc/classes/VisualServer.xml
msgid "Array is a tangent array."
-msgstr "数组是一个切线数组。"
+msgstr "数组是切线数组。"
#: doc/classes/VisualServer.xml
msgid "Array is a color array."
-msgstr "数组是一个颜色数组。"
+msgstr "数组是颜色数组。"
#: doc/classes/VisualServer.xml
msgid "Array is an UV coordinates array."
-msgstr "数组是一个 UV åæ ‡æ•°ç»„。"
+msgstr "数组是 UV åæ ‡æ•°ç»„。"
#: doc/classes/VisualServer.xml
msgid "Array is an UV coordinates array for the second UV coordinates."
@@ -83402,7 +83878,7 @@ msgstr "用于标记顶点数组的标志。"
#: doc/classes/VisualServer.xml
msgid "Flag used to mark a normal array."
-msgstr "用于标记正常数组的标志。"
+msgstr "用于标记法线数组的标志。"
#: doc/classes/VisualServer.xml
msgid "Flag used to mark a tangent array."
@@ -84338,9 +84814,8 @@ msgstr "在ç€è‰²å™¨è¯­è¨€ä¸­è¢«è½¬æ¢æˆ[code]uniform bool[/code]。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
#: doc/classes/VisualShaderNodeTransformUniform.xml
#: doc/classes/VisualShaderNodeVec3Uniform.xml
-#, fuzzy
msgid "A default value to be assigned within the shader."
-msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„è²æ¶…尔效果。"
+msgstr "该ç€è‰²å™¨å†…部分é…的默认值。"
#: doc/classes/VisualShaderNodeBooleanUniform.xml
#: doc/classes/VisualShaderNodeColorUniform.xml
@@ -84348,7 +84823,7 @@ msgstr "在å¯è§†åŒ–ç€è‰²å™¨å›¾ä¸­ä½¿ç”¨çš„è²æ¶…尔效果。"
#: doc/classes/VisualShaderNodeTransformUniform.xml
#: doc/classes/VisualShaderNodeVec3Uniform.xml
msgid "Enables usage of the [member default_value]."
-msgstr ""
+msgstr "å¯ç”¨ [member default_value]。"
#: doc/classes/VisualShaderNodeColorConstant.xml
msgid "A [Color] constant to be used within the visual shader graph."
@@ -84788,7 +85263,7 @@ msgid ""
"Virtual class to define custom [VisualShaderNode]s for use in the Visual "
"Shader Editor."
msgstr ""
-"用于定义自定义[VisualShaderNode]的虚拟类,以便在å¯è§†åŒ–ç€è‰²å™¨ç¼–辑器中使用。"
+"用于定义自定义 [VisualShaderNode] 的虚类,以便在å¯è§†åŒ–ç€è‰²å™¨ç¼–辑器中使用。"
#: doc/classes/VisualShaderNodeCustom.xml
msgid ""
@@ -85394,29 +85869,35 @@ msgstr ""
msgid ""
"A hint applied to the uniform, which controls the values it can take when "
"set through the inspector."
-msgstr ""
+msgstr "对 uniform 应用的æç¤ºï¼ŒæŽ§åˆ¶é€šè¿‡æ£€æŸ¥å™¨æ‰€èƒ½è®¾ç½®çš„值。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid ""
"Minimum value for range hints. Used if [member hint] is set to [constant "
"HINT_RANGE] or [constant HINT_RANGE_STEP]."
msgstr ""
+"范围æç¤ºçš„æœ€å°å€¼ã€‚会在 [member hint] 为 [constant HINT_RANGE] 或 [constant "
+"HINT_RANGE_STEP] 时使用。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid ""
"Maximum value for range hints. Used if [member hint] is set to [constant "
"HINT_RANGE] or [constant HINT_RANGE_STEP]."
msgstr ""
+"范围æç¤ºçš„æœ€å¤§å€¼ã€‚会在 [member hint] 为 [constant HINT_RANGE] 或 [constant "
+"HINT_RANGE_STEP] 时使用。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid ""
"Step (increment) value for the range hint with step. Used if [member hint] "
"is set to [constant HINT_RANGE_STEP]."
msgstr ""
+"带步长(增é‡ï¼‰çš„范围æç¤ºçš„æ­¥é•¿å€¼ã€‚会在 [member hint] 为 [constant "
+"HINT_RANGE_STEP] 时使用。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid "No hint used."
-msgstr ""
+msgstr "ä¸ä½¿ç”¨æç¤ºã€‚"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid ""
@@ -85424,6 +85905,8 @@ msgid ""
"[member min] and [member max]. Translated to [code]hint_range(min, max)[/"
"code] in shader code."
msgstr ""
+"æ ‡é‡å€¼çš„范围æç¤ºï¼Œä¼šå°†å¯èƒ½çš„输入é™åˆ¶åœ¨ [member min] å’Œ [member max] 之间。会"
+"被翻译为ç€è‰²å™¨ä»£ç ä¸­çš„ [code]hint_range(min, max)[/code]。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
msgid ""
@@ -85431,11 +85914,13 @@ msgid ""
"between [member min] and [member max], with a step (increment) of [member "
"step]). Translated to [code]hint_range(min, max, step)[/code] in shader code."
msgstr ""
+"æ ‡é‡å€¼çš„范围æç¤ºï¼Œå¸¦æ­¥é•¿ï¼Œä¼šå°†å¯èƒ½çš„输入é™åˆ¶åœ¨ [member min] å’Œ [member max] "
+"之间,步长(增é‡ï¼‰ä¸º [member step]。会被翻译为ç€è‰²å™¨ä»£ç ä¸­çš„ "
+"[code]hint_range(min, max, step)[/code]。"
#: doc/classes/VisualShaderNodeScalarUniform.xml
-#, fuzzy
msgid "Represents the size of the [enum Hint] enum."
-msgstr "表示[enum Monitor] enum的大å°ã€‚"
+msgstr "表示 [enum Hint] 枚举的大å°ã€‚"
#: doc/classes/VisualShaderNodeSwitch.xml
msgid "A boolean/vector function for use within the visual shader graph."
@@ -86036,7 +86521,7 @@ msgid ""
"Returns the vector that points in the direction of reflection. [code]a[/"
"code] is incident vector and [code]b[/code] is the normal vector."
msgstr ""
-"返回指å‘åå°„æ–¹å‘çš„å‘é‡ã€‚[code]a[/code]是入射å‘é‡ï¼Œ[code]b[/code]是法å‘é‡ã€‚"
+"返回指å‘åå°„æ–¹å‘çš„å‘é‡ã€‚[code]a[/code] 是入射å‘é‡ï¼Œ[code]b[/code] 是法å‘é‡ã€‚"
#: doc/classes/VisualShaderNodeVectorOp.xml
msgid ""
diff --git a/doc/translations/zh_TW.po b/doc/translations/zh_TW.po
index 3db6f2c82d..b07e7c7cc7 100644
--- a/doc/translations/zh_TW.po
+++ b/doc/translations/zh_TW.po
@@ -2850,7 +2850,12 @@ msgid "Gamepad button 22."
msgstr ""
#: doc/classes/@GlobalScope.xml
-msgid "Represents the maximum number of joystick buttons supported."
+msgid ""
+"The maximum number of game controller buttons supported by the engine. The "
+"actual limit may be lower on specific platforms:\n"
+"- Android: Up to 36 buttons.\n"
+"- Linux: Up to 80 buttons.\n"
+"- Windows and macOS: Up to 128 buttons."
msgstr ""
#: doc/classes/@GlobalScope.xml
@@ -3844,8 +3849,6 @@ msgid ""
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates. The 2D counterpart to [AABB] is "
"[Rect2].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get an AABB with a positive size.\n"
"[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses "
"integer coordinates."
msgstr ""
@@ -9449,15 +9452,17 @@ msgid "Represents the size of the [enum FFT_Size] enum."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
-msgid "Audio effect used for recording sound from a microphone."
+msgid "Audio effect used for recording the sound from an audio bus."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
msgid ""
-"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."
+"Allows the user to record the sound from an audio bus. This can include all "
+"audio output by Godot when used on the \"Master\" audio bus.\n"
+"Can be used (with an [AudioStreamMicrophone]) to record from a microphone.\n"
+"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."
msgstr ""
#: doc/classes/AudioEffectRecord.xml
@@ -15572,9 +15577,8 @@ msgstr ""
msgid ""
"Creates a local override for a theme [Color] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_color].\n"
+"the control.\n"
+"See also [method get_color], [method remove_color_override].\n"
"[b]Example of overriding a label's color and resetting it later:[/b]\n"
"[codeblock]\n"
"# Given the child Label node \"MyLabel\", override its font color with a "
@@ -15590,17 +15594,18 @@ msgstr ""
msgid ""
"Creates a local override for a theme constant with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override cannot be removed, but it can be overridden with "
-"the corresponding default value.\n"
-"See also [method get_constant]."
+"the control.\n"
+"See also [method get_constant], [method remove_constant_override]."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [Font] with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_font_override] instead.\n"
"See also [method get_font]."
msgstr ""
@@ -15608,8 +15613,10 @@ msgstr ""
msgid ""
"Creates a local override for a theme icon with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value.\n"
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_icon_override] instead.\n"
"See also [method get_icon]."
msgstr ""
@@ -15617,16 +15624,20 @@ msgstr ""
msgid ""
"Creates a local override for a theme shader with the specified [code]name[/"
"code]. Local overrides always take precedence when fetching theme items for "
-"the control. An override can be removed by assigning it a [code]null[/code] "
-"value."
+"the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_shader_override] instead."
msgstr ""
#: doc/classes/Control.xml
msgid ""
"Creates a local override for a theme [StyleBox] with the specified "
"[code]name[/code]. Local overrides always take precedence when fetching "
-"theme items for the control. An override can be removed by assigning it a "
-"[code]null[/code] value.\n"
+"theme items for the control.\n"
+"[b]Note:[/b] An override can be removed by assigning it a [code]null[/code] "
+"value. This behavior is deprecated and will be removed in 4.0, use [method "
+"remove_stylebox_override] instead.\n"
"See also [method get_stylebox].\n"
"[b]Example of modifying a property in a StyleBox by duplicating it:[/b]\n"
"[codeblock]\n"
@@ -15985,6 +15996,39 @@ msgid ""
msgstr ""
#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [Color] with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a constant with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a [Font] with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for an icon with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid "Removes a theme override for a shader with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
+#, fuzzy
+msgid ""
+"Removes a theme override for a [StyleBox] with the given [code]name[/code]."
+msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+
+#: doc/classes/Control.xml
msgid ""
"Sets the anchor identified by [code]margin[/code] constant from [enum "
"Margin] enum to value [code]anchor[/code]. A setter method for [member "
@@ -16471,7 +16515,15 @@ msgid ""
"its [member mouse_filter] lets the event reach it.\n"
"[b]Note:[/b] [signal mouse_exited] will be emitted if the mouse enters a "
"child [Control] node, even if the mouse cursor is still inside the parent's "
-"[code]Rect[/code] area."
+"[code]Rect[/code] area.\n"
+"If you want to check whether the mouse truly left the area, ignoring any top "
+"nodes, you can use code like this:\n"
+"[codeblock]\n"
+"func _on_mouse_exited():\n"
+" if not Rect2(Vector2(), rect_size)."
+"has_point(get_local_mouse_position()):\n"
+" # Not hovering over area.\n"
+"[/codeblock]"
msgstr ""
#: doc/classes/Control.xml
@@ -22259,111 +22311,247 @@ msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Version Control System (VCS) interface which reads and writes to the local "
+"Version Control System (VCS) interface, which reads and writes to the local "
"VCS in use."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Used by the editor to display VCS extracted information in the editor. The "
-"implementation of this API is included in VCS addons, which are essentially "
-"GDNative plugins that need to be put into the project folder. These VCS "
-"addons are scripts which are attached (on demand) to the object instance of "
-"[code]EditorVCSInterface[/code]. All the functions listed below, instead of "
-"performing the task themselves, they call the internally defined functions "
-"in the VCS addons to provide a plug-n-play experience."
+"Defines the API that the editor uses to extract information from the "
+"underlying VCS. The implementation of this API is included in VCS plugins, "
+"which are scripts that inherit [EditorVCSInterface] and are attached (on "
+"demand) to the singleton instance of [EditorVCSInterface]. Instead of "
+"performing the task themselves, all the virtual functions listed below are "
+"calling the internally overridden functions in the VCS plugins to provide a "
+"plug-n-play experience. A custom VCS plugin is supposed to inherit from "
+"[EditorVCSInterface] and override these virtual functions."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Checks out a [code]branch_name[/code] in the VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Commits the currently staged changes and applies the commit [code]msg[/code] "
+"to the resulting commit."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Creates a new branch named [code]branch_name[/code] in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Creates a version commit if the addon is initialized, else returns without "
-"doing anything. Uses the files which have been staged previously, with the "
-"commit message set to a value as provided as in the argument."
+"Creates a new remote destination with name [code]remote_name[/code] and "
+"points it to [code]remote_url[/code]. This can be both an HTTPS remote or an "
+"SSH remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Discards the changes made in file present at [code]file_path[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns an [Array] of [Dictionary] objects containing the diff output from "
-"the VCS in use, if a VCS addon is initialized, else returns an empty [Array] "
-"object. The diff contents also consist of some contextual lines which "
-"provide context to the observed line change in the file.\n"
-"Each [Dictionary] object has the line diff contents under the keys:\n"
-"- [code]\"content\"[/code] to store a [String] containing the line contents\n"
-"- [code]\"status\"[/code] to store a [String] which contains [code]\"+\"[/"
-"code] in case the content is a line addition but it stores a [code]\"-\"[/"
-"code] in case of deletion and an empty string in the case the line content "
-"is neither an addition nor a deletion.\n"
-"- [code]\"new_line_number\"[/code] to store an integer containing the new "
-"line number of the line content.\n"
-"- [code]\"line_count\"[/code] to store an integer containing the number of "
-"lines in the line content.\n"
-"- [code]\"old_line_number\"[/code] to store an integer containing the old "
-"line number of the line content.\n"
-"- [code]\"offset\"[/code] to store the offset of the line change since the "
-"first contextual line content."
+"Fetches new changes from the remote, but doesn't write changes to the "
+"current working directory. Equivalent to [code]git fetch[/code]."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns a [Dictionary] containing the path of the detected file change "
-"mapped to an integer signifying what kind of change the corresponding file "
-"has experienced.\n"
-"The following integer values are being used to signify that the detected "
-"file is:\n"
-"- [code]0[/code]: New to the VCS working directory\n"
-"- [code]1[/code]: Modified\n"
-"- [code]2[/code]: Renamed\n"
-"- [code]3[/code]: Deleted\n"
-"- [code]4[/code]: Typechanged"
+"Gets an instance of an [Array] of [String]s containing available branch "
+"names in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
-msgid "Returns the project name of the VCS working directory."
+msgid "Gets the current branch name defined in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns the name of the VCS if the VCS has been initialized, else return an "
-"empty string."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_file], "
+"[method create_diff_hunk], [method create_diff_line], [method "
+"add_line_diffs_into_diff_hunk] and [method add_diff_hunks_into_diff_file]), "
+"each containing information about a diff. If [code]identifier[/code] is a "
+"file path, returns a file diff, and if it is a commit identifier, then "
+"returns a commit diff."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Initializes the VCS addon if not already. Uses the argument value as the "
-"path to the working directory of the project. Creates the initial commit if "
-"required. Returns [code]true[/code] if no failure occurs, else returns "
-"[code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_diff_hunk]), "
+"each containing a line diff between a file at [code]file_path[/code] and the "
+"[code]text[/code] which is passed in."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the addon is ready to respond to function "
-"calls, else returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_status_file]), "
+"each containing the status data of every modified file in the project folder."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Returns [code]true[/code] if the VCS addon has been initialized, else "
-"returns [code]false[/code]."
+"Returns an [Array] of [Dictionary] items (see [method create_commit]), each "
+"containing the data for a past commit."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Shuts down the VCS addon to allow cleanup code to run on call. Returns "
-"[code]true[/code] is no failure occurs, else returns [code]false[/code]."
+"Returns an [Array] of [String]s, each containing the name of a remote "
+"configured in the VCS."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
+#, fuzzy
+msgid "Returns the name of the underlying VCS provider."
+msgstr "å›žå‚³åƒæ•¸çš„æ­£å¼¦å€¼ã€‚"
+
+#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Stages the file which should be committed when [method EditorVCSInterface."
-"commit] is called. Argument should contain the absolute path."
+"Initializes the VCS plugin when called from the editor. Returns whether or "
+"not the plugin was successfully initialized. A VCS project is initialized at "
+"[code]project_path[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pulls changes from the remote. This can give rise to merge conflicts."
msgstr ""
#: doc/classes/EditorVCSInterface.xml
msgid ""
-"Unstages the file which was staged previously to be committed, so that it is "
-"no longer committed when [method EditorVCSInterface.commit] is called. "
-"Argument should contain the absolute path."
+"Pushes changes to the [code]remote[/code]. Optionally, if [code]force[/code] "
+"is set to true, a force push will override the change history already "
+"present on the remote."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a branch from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Remove a remote from the local VCS."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Set user credentials in the underlying VCS. [code]username[/code] and "
+"[code]password[/code] are used only during HTTPS authentication unless not "
+"already mentioned in the remote URL. [code]ssh_public_key_path[/code], "
+"[code]ssh_private_key_path[/code], and [code]ssh_passphrase[/code] are only "
+"used during SSH authentication."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Shuts down VCS plugin instance. Called when the user either closes the "
+"editor or shuts down the VCS plugin through the editor UI."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Stages the file present at [code]file_path[/code] to the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Unstages the file present at [code]file_path[/code] from the staged area to "
+"the unstaged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]diff_hunks[/code] into a "
+"[code]diff_file[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to add an array of [code]line_diffs[/code] into a "
+"[code]diff_hunk[/code]."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a commit [Dictionary] item. [code]msg[/code] is "
+"the commit message of the commit. [code]author[/code] is a human-readable "
+"string containing the author's details, e.g. the email and name configured "
+"in the VCS. [code]id[/code] is the identifier of the commit, in whichever "
+"format your VCS may provide an identifier to commits. [code]date[/code] is "
+"directly added to the commit item and displayed in the editor, and hence, it "
+"shall be a well-formatted, human-readable date string."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing old and new "
+"diff file paths."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing diff hunk "
+"data. [code]old_start[/code] is the starting line number in old file. "
+"[code]new_start[/code] is the starting line number in new file. "
+"[code]old_lines[/code] is the number of lines in the old file. "
+"[code]new_lines[/code] is the number of lines in the new file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] for storing a line diff. "
+"[code]new_line_no[/code] is the line number in the new file (can be "
+"[code]-1[/code] if the line is deleted). [code]old_line_no[/code] is the "
+"line number in the old file (can be [code]-1[/code] if the line is added). "
+"[code]content[/code] is the diff text. [code]content[/code] is the diff "
+"text. [code]status[/code] is a single character string which stores the line "
+"origin."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid ""
+"Helper function to create a [code]Dictionary[/code] used by editor to read "
+"the status of a file."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "Pops up an error message in the edior."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A new file has been added."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been modified."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been renamed."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been deleted."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "An earlier added file has been typechanged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is left unmerged."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A commit is encountered from the commit area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the staged area."
+msgstr ""
+
+#: doc/classes/EditorVCSInterface.xml
+msgid "A file is encountered from the unstaged area."
msgstr ""
#: doc/classes/EncodedObjectAsID.xml
@@ -23810,9 +23998,14 @@ msgstr ""
#: doc/classes/FileDialog.xml
msgid ""
-"Adds [code]filter[/code] as a custom filter; [code]filter[/code] should be "
-"of the form [code]\"filename.extension ; Description\"[/code]. For example, "
-"[code]\"*.png ; PNG Images\"[/code]."
+"Adds [code]filter[/code] to the list of filters, which restricts what files "
+"can be picked.\n"
+"A [code]filter[/code] should be of the form [code]\"filename.extension ; "
+"Description\"[/code], where filename and extension can be [code]*[/code] to "
+"match any string. Filters starting with [code].[/code] (i.e. empty "
+"filenames) are not allowed.\n"
+"Example filters: [code]\"*.png ; PNG Images\"[/code], [code]\"project."
+"godot ; Godot Project\"[/code]."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -23869,7 +24062,9 @@ msgstr ""
msgid ""
"The available file type filters. For example, this shows only [code].png[/"
"code] and [code].gd[/code] files: [code]set_filters(PoolStringArray([\"*."
-"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]."
+"png ; PNG Images\",\"*.gd ; GDScript Files\"]))[/code]. Multiple file types "
+"can also be specified in a single filter. [code]\"*.png, *.jpg, *.jpeg ; "
+"Supported Images\"[/code] will show both PNG and JPEG files when selected."
msgstr ""
#: doc/classes/FileDialog.xml
@@ -25599,6 +25794,95 @@ msgstr ""
msgid "The number of color samples that will be obtained from the [Gradient]."
msgstr ""
+#: doc/classes/GradientTexture2D.xml
+msgid "Gradient-filled 2D texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture uses a [Gradient] to fill the texture data in 2D space. The "
+"gradient is filled according to the specified [member fill] and [member "
+"repeat] types using colors obtained from the gradient. The texture does not "
+"necessarily represent an exact copy of the gradient, but instead an "
+"interpolation of samples obtained from the gradient at fixed steps (see "
+"[member width] and [member height])."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill type, one of the [enum Fill] values. The texture is filled "
+"by interpolating colors starting from [member fill_from] to [member fill_to] "
+"offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The initial offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The final offset used to fill the texture specified in UV coordinates."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+#, fuzzy
+msgid "The [Gradient] used to fill the texture."
+msgstr "å›žå‚³åƒæ•¸çš„æ­£å¼¦å€¼ã€‚"
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of vertical color samples that will be obtained from the "
+"[Gradient], which also represents the texture's height."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient repeat type, one of the [enum Repeat] values. The texture is "
+"filled starting from [member fill_from] to [member fill_to] offsets by "
+"default, but the gradient fill can be repeated to cover the entire texture."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"If [code]true[/code], the generated texture will support high dynamic range "
+"([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work "
+"if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/"
+"code], the generated texture will use low dynamic range; overbright colors "
+"will be clamped ([constant Image.FORMAT_RGBA8] format)."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The number of horizontal color samples that will be obtained from the "
+"[Gradient], which also represents the texture's width."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a straight line."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid "The colors are linearly interpolated in a circular pattern."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The gradient fill is restricted to the range defined by [member fill_from] "
+"to [member fill_to] offsets."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, repeating the same pattern in both directions."
+msgstr ""
+
+#: doc/classes/GradientTexture2D.xml
+msgid ""
+"The texture is filled starting from [member fill_from] to [member fill_to] "
+"offsets, mirroring the pattern in both directions."
+msgstr ""
+
#: doc/classes/GraphEdit.xml
msgid ""
"GraphEdit is an area capable of showing various GraphNodes. It manages "
@@ -29615,7 +29899,7 @@ msgstr ""
#: doc/classes/InputEventMIDI.xml
msgid ""
"Returns a value indicating the type of message for this MIDI signal. This is "
-"a member of the MidiMessageList enum.\n"
+"a member of the [enum @GlobalScope.MidiMessageList] enum.\n"
"For MIDI messages between 0x80 and 0xEF, only the left half of the bits are "
"returned as this value, as the other part is the channel (ex: 0x94 becomes "
"0x9). For MIDI messages from 0xF0 to 0xFF, the value is returned as-is.\n"
@@ -33512,7 +33796,7 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns specified edge associated with given face.\n"
-"Edge argument must 2 or less because a face only has three edges."
+"Edge argument must be either 0, 1, or 2 because a face only has three edges."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33526,7 +33810,8 @@ msgstr ""
#: doc/classes/MeshDataTool.xml
msgid ""
"Returns the specified vertex of the given face.\n"
-"Vertex argument must be 2 or less because faces contain three vertices."
+"Vertex argument must be either 0, 1, or 2 because faces contain three "
+"vertices."
msgstr ""
#: doc/classes/MeshDataTool.xml
@@ -33750,7 +34035,7 @@ msgstr ""
#: doc/classes/MeshInstance2D.xml doc/classes/MultiMeshInstance2D.xml
msgid ""
"The normal map that will be used if using the default [CanvasItemMaterial].\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -34740,7 +35025,7 @@ msgid ""
"set_target_location] in order for this to be accurate."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
"Returns the reachable final location in global coordinates. This can change "
"if the navigation path is altered in any way. Because of this, it would be "
@@ -34809,9 +35094,9 @@ msgid ""
"path."
msgstr ""
-#: doc/classes/NavigationAgent.xml
+#: doc/classes/NavigationAgent.xml doc/classes/NavigationAgent2D.xml
msgid ""
-"Sends the given velocity to the collision avoidance algorithm. It will "
+"Sends the passed in velocity to the collision avoidance algorithm. It will "
"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
"is complete, it will emit the [signal velocity_computed] signal."
msgstr ""
@@ -34902,12 +35187,6 @@ msgid ""
msgstr ""
#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Returns the reachable final location in global coordinates. This can change "
-"if the navigation path is altered in any way."
-msgstr ""
-
-#: doc/classes/NavigationAgent2D.xml
#, fuzzy
msgid ""
"Returns which index the agent is currently on in the navigation path's "
@@ -34933,13 +35212,6 @@ msgid ""
"to make the agent a child of a [Navigation2D] node."
msgstr ""
-#: doc/classes/NavigationAgent2D.xml
-msgid ""
-"Sends the passed in velocity to the collision avoidance algorithm. It will "
-"adjust the velocity to avoid collisions. Once the adjustment to the velocity "
-"is complete, it will emit the [signal velocity_computed] signal."
-msgstr ""
-
#: doc/classes/NavigationMesh.xml
msgid "A mesh to approximate the walkable areas and obstacles."
msgstr ""
@@ -35289,7 +35561,7 @@ msgid ""
"2D obstacle used in navigation for collision avoidance. The obstacle needs "
"navigation data to work correctly. This can be done by having the obstacle "
"as a child of a [Navigation2D] node, or using [method set_navigation]. "
-"[NavigationObstacle] is physics safe."
+"[NavigationObstacle2D] is physics safe."
msgstr ""
#: doc/classes/NavigationObstacle2D.xml
@@ -38442,6 +38714,9 @@ msgid ""
"If [code]blocking[/code] is [code]false[/code], the Godot thread will "
"continue while the new process runs. It is not possible to retrieve the "
"shell output in non-blocking mode, so [code]output[/code] will be empty.\n"
+"On Windows, if [code]open_console[/code] is [code]true[/code] and process is "
+"console app, new terminal window will be opened, it's ignored on other "
+"platforms.\n"
"The return value also depends on the blocking mode. When blocking, the "
"method will return an exit code of the process. When non-blocking, the "
"method returns a process ID, which you can use to monitor the process (and "
@@ -40191,6 +40466,10 @@ msgid ""
"to [CPUParticles] by selecting the node, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choosing [b]Convert to "
"CPUParticles[/b].\n"
+"[b]Note:[/b] On macOS, [Particles] rendering is much slower than "
+"[CPUParticles] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_aabb] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 3D editor viewport then choose [b]Generate Visibility "
@@ -40311,6 +40590,10 @@ msgid ""
"[Particles2D] to [CPUParticles2D] by selecting the node, clicking the "
"[b]Particles[/b] menu at the top of the 2D editor viewport then choosing "
"[b]Convert to CPUParticles2D[/b].\n"
+"[b]Note:[/b] On macOS, [Particles2D] rendering is much slower than "
+"[CPUParticles2D] due to transform feedback being implemented on the CPU "
+"instead of the GPU. Consider using [CPUParticles2D] instead when targeting "
+"macOS.\n"
"[b]Note:[/b] After working on a Particles node, remember to update its "
"[member visibility_rect] by selecting it, clicking the [b]Particles[/b] menu "
"at the top of the 2D editor viewport then choose [b]Generate Visibility "
@@ -44778,7 +45061,9 @@ msgid ""
"[b]Example:[/b]\n"
"[codeblock]\n"
"ProjectSettings.set_setting(\"application/config/name\", \"Example\")\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"This can also be used to erase custom project settings. To do this change "
+"the setting value to [code]null[/code]."
msgstr ""
#: doc/classes/ProjectSettings.xml
@@ -45541,6 +45826,18 @@ msgstr ""
#: doc/classes/ProjectSettings.xml
msgid ""
+"Load the previously opened VCS plugin when the editor starts up. This is set "
+"to [code]true[/code] whenever a new VCS plugin is initialized."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
+"Last loaded VCS plugin name. Used to autoload the plugin when the editor "
+"starts up."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml
+msgid ""
"Default value for [member ScrollContainer.scroll_deadzone], which will be "
"used for all [ScrollContainer]s unless overridden."
msgstr ""
@@ -48139,9 +48436,7 @@ msgid ""
"[Rect2] consists of a position, a size, and several utility functions. It is "
"typically used for fast overlap tests.\n"
"It uses floating-point coordinates.\n"
-"The 3D counterpart to [Rect2] is [AABB].\n"
-"Negative values for [member size] are not supported and will not work for "
-"most methods. Use [method abs] to get a Rect2 with a positive size."
+"The 3D counterpart to [Rect2] is [AABB]."
msgstr ""
#: doc/classes/Rect2.xml
@@ -51487,6 +51782,12 @@ msgstr ""
#: doc/classes/ScriptEditor.xml
msgid ""
+"Reload all currently opened scripts from disk in case the file contents are "
+"newer."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml
+msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
@@ -52254,6 +52555,16 @@ msgid ""
"values."
msgstr ""
+#: doc/classes/Slider.xml
+msgid ""
+"Emitted when dragging stops. If [code]value_changed[/code] is true, [member "
+"Range.value] is different from the value when you started the dragging."
+msgstr ""
+
+#: doc/classes/Slider.xml
+msgid "Emitted when dragging is started."
+msgstr ""
+
#: doc/classes/SliderJoint.xml
msgid "Slider between two PhysicsBodies in 3D."
msgstr ""
@@ -52960,7 +53271,7 @@ msgstr ""
#: doc/classes/SpatialMaterial.xml
msgid ""
"Texture that specifies the per-pixel normal of the detail overlay.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -53158,7 +53469,7 @@ msgid ""
"you can use [method SurfaceTool.generate_normals] and [method SurfaceTool."
"generate_tangents] to automatically generate normals and tangents "
"respectively.\n"
-"[b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. "
+"[b]Note:[/b] Godot expects the normal map to use X+, Y+, and Z+ coordinates. "
"See [url=http://wiki.polycount.com/wiki/"
"Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for "
"a comparison of normal map coordinates expected by popular engines."
@@ -54293,13 +54604,13 @@ msgid "Represents the size of the [enum DrawFlags] enum."
msgstr ""
#: doc/classes/SpriteFrames.xml
-msgid "Sprite frame library for AnimatedSprite."
+msgid "Sprite frame library for AnimatedSprite and AnimatedSprite3D."
msgstr ""
#: doc/classes/SpriteFrames.xml
msgid ""
-"Sprite frame library for [AnimatedSprite]. Contains frames and animation "
-"data for playback.\n"
+"Sprite frame library for an [AnimatedSprite] or [AnimatedSprite3D] node. "
+"Contains frames and animation data for playback.\n"
"[b]Note:[/b] You can associate a set of normal maps by creating additional "
"[SpriteFrames] resources with a [code]_normal[/code] suffix. For example, "
"having 2 [SpriteFrames] resources [code]run[/code] and [code]run_normal[/"
@@ -60764,7 +61075,9 @@ msgid ""
"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
"looks best.\n"
"[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
-"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]\n"
+"[b]Note:[/b] Tween methods will return [code]false[/code] if the requested "
+"operation cannot be completed."
msgstr ""
#: doc/classes/Tween.xml
@@ -61869,9 +62182,17 @@ msgid ""
msgstr ""
#: doc/classes/Vector2.xml
-#, fuzzy
-msgid "Returns the cross product of this vector and [code]with[/code]."
-msgstr "計算兩個å‘é‡çš„外ç©ã€‚"
+msgid ""
+"Returns the 2D analog of the cross product for this vector and [code]with[/"
+"code].\n"
+"This is the signed area of the parallelogram formed by the two vectors. If "
+"the second vector is clockwise from the first vector, then the cross product "
+"is the positive area. If counter-clockwise, the cross product is the "
+"negative area.\n"
+"[b]Note:[/b] Cross product is not defined in 2D mathematically. This method "
+"embeds the 2D vectors in the XY plane of 3D space and uses their cross "
+"product's Z component as the analog."
+msgstr ""
#: doc/classes/Vector2.xml
msgid ""
diff --git a/drivers/gles3/rasterizer_array.h b/drivers/gles3/rasterizer_array.h
deleted file mode 100644
index 9762e78d54..0000000000
--- a/drivers/gles3/rasterizer_array.h
+++ /dev/null
@@ -1,421 +0,0 @@
-/*************************************************************************/
-/* rasterizer_array.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 RASTERIZER_ARRAY_H
-#define RASTERIZER_ARRAY_H
-
-/**
- * Fast single-threaded growable array for POD types.
- * For use in render drivers, not for general use.
- * TO BE REPLACED by local_vector.
- */
-
-#include "core/os/memory.h"
-#include <string.h>
-
-#include "core/templates/local_vector.h"
-#include "core/templates/vector.h"
-
-// very simple non-growable array, that keeps track of the size of a 'unit'
-// which can be cast to whatever vertex format FVF required, and is initially
-// created with enough memory to hold the biggest FVF.
-// This allows multiple FVFs to use the same array.
-class RasterizerUnitArrayGLES3 {
-public:
- RasterizerUnitArrayGLES3() {
- _list = nullptr;
- free();
- }
- ~RasterizerUnitArrayGLES3() { free(); }
-
- uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; }
- const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; }
-
- int size() const { return _size; }
- int max_size() const { return _max_size; }
-
- void free() {
- if (_list) {
- memdelete_arr(_list);
- _list = 0;
- }
- _size = 0;
- _max_size = 0;
- _max_size_bytes = 0;
- _unit_size_bytes = 0;
- }
-
- void create(int p_max_size_units, int p_max_unit_size_bytes) {
- free();
-
- _max_unit_size_bytes = p_max_unit_size_bytes;
- _max_size = p_max_size_units;
- _max_size_bytes = p_max_size_units * p_max_unit_size_bytes;
-
- if (_max_size_bytes) {
- _list = memnew_arr(uint8_t, _max_size_bytes);
- }
- }
-
- void prepare(int p_unit_size_bytes) {
- _unit_size_bytes = p_unit_size_bytes;
- _size = 0;
- }
-
- // several items at a time
- uint8_t *request(int p_num_items = 1) {
- int old_size = _size;
- _size += p_num_items;
-
- if (_size <= _max_size) {
- return get_unit(old_size);
- }
-
- // revert
- _size = old_size;
- return nullptr;
- }
-
-private:
- uint8_t *_list;
- int _size; // in units
- int _max_size; // in units
- int _max_size_bytes;
- int _unit_size_bytes;
- int _max_unit_size_bytes;
-};
-
-template <class T>
-class RasterizerArray {
-public:
- RasterizerArray() {
- _list = 0;
- _size = 0;
- _max_size = 0;
- }
- ~RasterizerArray() { free(); }
-
- T &operator[](unsigned int ui) { return _list[ui]; }
- const T &operator[](unsigned int ui) const { return _list[ui]; }
-
- void free() {
- if (_list) {
- memdelete_arr(_list);
- _list = 0;
- }
- _size = 0;
- _max_size = 0;
- }
-
- void create(int p_size) {
- free();
- if (p_size) {
- _list = memnew_arr(T, p_size);
- }
- _size = 0;
- _max_size = p_size;
- }
-
- void reset() { _size = 0; }
-
- T *request_with_grow() {
- T *p = request();
- if (!p) {
- grow();
- return request_with_grow();
- }
- return p;
- }
-
- // none of that inefficient pass by value stuff here, thanks
- T *request() {
- if (_size < _max_size) {
- return &_list[_size++];
- }
- return 0;
- }
-
- // several items at a time
- T *request(int p_num_items) {
- int old_size = _size;
- _size += p_num_items;
-
- if (_size <= _max_size) {
- return &_list[old_size];
- }
-
- // revert
- _size = old_size;
- return 0;
- }
-
- int size() const { return _size; }
- int max_size() const { return _max_size; }
- const T *get_data() const { return _list; }
-
- bool copy_from(const RasterizerArray<T> &o) {
- // no resizing done here, it should be done manually
- if (o.size() > _max_size)
- return false;
-
- // pod types only please!
- memcpy(_list, o.get_data(), o.size() * sizeof(T));
- _size = o.size();
- return true;
- }
-
- // if you want this to be cheap, call reset before grow,
- // to ensure there is no data to copy
- void grow() {
- unsigned int new_max_size = _max_size * 2;
- if (!new_max_size)
- new_max_size = 1;
-
- T *new_list = memnew_arr(T, new_max_size);
-
- // copy .. pod types only
- if (_list) {
- memcpy(new_list, _list, _size * sizeof(T));
- }
-
- unsigned int new_size = size();
- free();
- _list = new_list;
- _size = new_size;
- _max_size = new_max_size;
- }
-
-private:
- T *_list;
- int _size;
- int _max_size;
-};
-
-template <class T>
-class RasterizerArray_non_pod {
-public:
- RasterizerArray_non_pod() {
- _size = 0;
- }
-
- const T &operator[](unsigned int ui) const { return _list[ui]; }
-
- void create(int p_size) {
- _list.resize(p_size);
- _size = 0;
- }
- void reset() { _size = 0; }
-
- void push_back(const T &val) {
- while (true) {
- if (_size < max_size()) {
- _list.set(_size, val);
- _size++;
- return;
- }
-
- grow();
- }
- }
-
- int size() const { return _size; }
- int max_size() const { return _list.size(); }
-
-private:
- void grow() {
- unsigned int new_max_size = _list.size() * 2;
- if (!new_max_size)
- new_max_size = 1;
- _list.resize(new_max_size);
- }
-
- Vector<T> _list;
- int _size;
-};
-
-// very simple non-growable array, that keeps track of the size of a 'unit'
-// which can be cast to whatever vertex format FVF required, and is initially
-// created with enough memory to hold the biggest FVF.
-// This allows multiple FVFs to use the same array.
-class RasterizerUnitArray {
-public:
- RasterizerUnitArray() {
- _list = nullptr;
- free();
- }
- ~RasterizerUnitArray() { free(); }
-
- uint8_t *get_unit(unsigned int ui) { return &_list[ui * _unit_size_bytes]; }
- const uint8_t *get_unit(unsigned int ui) const { return &_list[ui * _unit_size_bytes]; }
-
- int size() const { return _size; }
- int max_size() const { return _max_size; }
- int get_unit_size_bytes() const { return _unit_size_bytes; }
-
- void free() {
- if (_list) {
- memdelete_arr(_list);
- _list = 0;
- }
- _size = 0;
- _max_size = 0;
- _max_size_bytes = 0;
- _unit_size_bytes = 0;
- }
-
- void create(int p_max_size_units, int p_max_unit_size_bytes) {
- free();
-
- _max_unit_size_bytes = p_max_unit_size_bytes;
- _max_size = p_max_size_units;
- _max_size_bytes = p_max_size_units * p_max_unit_size_bytes;
-
- if (_max_size_bytes) {
- _list = memnew_arr(uint8_t, _max_size_bytes);
- }
- }
-
- void prepare(int p_unit_size_bytes) {
- _unit_size_bytes = p_unit_size_bytes;
- _size = 0;
- }
-
- // several items at a time
- uint8_t *request(int p_num_items = 1) {
- int old_size = _size;
- _size += p_num_items;
-
- if (_size <= _max_size) {
- return get_unit(old_size);
- }
-
- // revert
- _size = old_size;
- return nullptr;
- }
-
-private:
- uint8_t *_list;
- int _size; // in units
- int _max_size; // in units
- int _max_size_bytes;
- int _unit_size_bytes;
- int _max_unit_size_bytes;
-};
-
-template <class T, bool force_trivial = false>
-class RasterizerPooledList {
- LocalVector<T, uint32_t, force_trivial> list;
- LocalVector<uint32_t, uint32_t, true> freelist;
-
- // not all list members are necessarily used
- int _used_size;
-
-public:
- RasterizerPooledList() {
- _used_size = 0;
- }
-
- int estimate_memory_use() const {
- return (list.size() * sizeof(T)) + (freelist.size() * sizeof(uint32_t));
- }
-
- const T &operator[](uint32_t p_index) const {
- return list[p_index];
- }
- T &operator[](uint32_t p_index) {
- return list[p_index];
- }
-
- int size() const { return _used_size; }
-
- // returns the list id of the allocated item
- uint32_t alloc() {
- uint32_t id = 0;
- _used_size++;
-
- if (freelist.size()) {
- // pop from freelist
- int new_size = freelist.size() - 1;
- id = freelist[new_size];
- freelist.resize(new_size);
- return id;
- // return &list[r_id];
- }
-
- id = list.size();
- list.resize(id + 1);
- return id;
- // return &list[r_id];
- }
- void free(const uint32_t &p_id) {
- // should not be on free list already
- CRASH_COND(p_id >= list.size());
- freelist.push_back(p_id);
- _used_size--;
- }
-};
-
-template <class T, bool force_trivial = false>
-class RasterizerPooledIndirectList {
-public:
- const T &operator[](uint32_t p_index) const {
- return *_list[p_index];
- }
- T &operator[](uint32_t p_index) {
- return *_list[p_index];
- }
-
- uint32_t alloc() {
- uint32_t id = _list.alloc();
- _list[id] = memnew(T);
- return id;
- }
- void free(const uint32_t &p_id) {
- CRASH_COND(!_list[p_id]);
- memdelete_notnull(_list[p_id]);
- _list[p_id] = nullptr;
- _list.free(p_id);
- }
-
- ~RasterizerPooledIndirectList() {
- // autodelete
- for (int n = 0; n < _list.size(); n++) {
- if (_list[n]) {
- memdelete_notnull(_list[n]);
- }
- }
- }
-
-private:
- RasterizerPooledList<T *, true> _list;
-};
-
-#endif // RASTERIZER_ARRAY_H
diff --git a/drivers/gles3/rasterizer_asserts.h b/drivers/gles3/rasterizer_asserts.h
deleted file mode 100644
index b39357bffd..0000000000
--- a/drivers/gles3/rasterizer_asserts.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* rasterizer_asserts.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 RASTERIZER_ASSERTS_H
-#define RASTERIZER_ASSERTS_H
-
-// For flow control checking, we want an easy way to apply asserts that occur in debug development builds only.
-// This is enforced by outputting a warning which will fail CI checks if the define is set in a PR.
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
-// only uncomment this define for error checking in development, not in the main repository
-// as these checks will slow things down in debug builds.
-//#define RASTERIZER_EXTRA_CHECKS
-#endif
-
-#ifdef RASTERIZER_EXTRA_CHECKS
-#ifndef _MSC_VER
-#warning do not define RASTERIZER_EXTRA_CHECKS in main repository builds
-#endif
-#define RAST_DEV_DEBUG_ASSERT(a) CRASH_COND(!(a))
-#else
-#define RAST_DEV_DEBUG_ASSERT(a)
-#endif
-
-// Also very useful, an assert check that only occurs in debug tools builds
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
-#define RAST_DEBUG_ASSERT(a) CRASH_COND(!(a))
-#else
-#define RAST_DEBUG_ASSERT(a)
-#endif
-
-// Thin wrapper around ERR_FAIL_COND to allow us to make it debug only
-#ifdef DEBUG_ENABLED
-#define RAST_FAIL_COND(m_cond) ERR_FAIL_COND(m_cond)
-#else
-#define RAST_FAIL_COND(m_cond) \
- if (m_cond) { \
- }
-#endif
-
-#endif // RASTERIZER_ASSERTS_H
diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.cpp b/drivers/gles3/rasterizer_canvas_base_gles3.cpp
deleted file mode 100644
index 899e89cbce..0000000000
--- a/drivers/gles3/rasterizer_canvas_base_gles3.cpp
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*************************************************************************/
-/* rasterizer_canvas_base_gles3.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 "rasterizer_canvas_base_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
-
-#include "core/os/os.h"
-#include "drivers/gles3/rasterizer_asserts.h"
-#include "rasterizer_scene_gles3.h"
-
-#include "core/config/project_settings.h"
-#include "servers/rendering/rendering_server_default.h"
-
-#ifndef GLES_OVER_GL
-#define glClearDepth glClearDepthf
-#endif
-
-static _FORCE_INLINE_ void store_transform3d(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.elements[0][0];
- p_array[1] = p_mtx.basis.elements[1][0];
- p_array[2] = p_mtx.basis.elements[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.basis.elements[0][1];
- p_array[5] = p_mtx.basis.elements[1][1];
- p_array[6] = p_mtx.basis.elements[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.basis.elements[0][2];
- p_array[9] = p_mtx.basis.elements[1][2];
- p_array[10] = p_mtx.basis.elements[2][2];
- p_array[11] = 0;
- p_array[12] = p_mtx.origin.x;
- p_array[13] = p_mtx.origin.y;
- p_array[14] = p_mtx.origin.z;
- p_array[15] = 1;
-}
-
-RID RasterizerCanvasBaseGLES3::light_internal_create() {
- return RID();
-}
-
-void RasterizerCanvasBaseGLES3::light_internal_update(RID p_rid, Light *p_light) {
-}
-
-void RasterizerCanvasBaseGLES3::light_internal_free(RID p_rid) {
-}
-
-RID RasterizerCanvasBaseGLES3::light_create() {
- return RID();
-}
-
-void RasterizerCanvasBaseGLES3::light_set_texture(RID p_rid, RID p_texture) {
-}
-
-void RasterizerCanvasBaseGLES3::light_set_use_shadow(RID p_rid, bool p_enable) {
-}
-
-void RasterizerCanvasBaseGLES3::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
-}
-
-void RasterizerCanvasBaseGLES3::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) {
-}
-
-void RasterizerCanvasBaseGLES3::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
-}
-
-RID RasterizerCanvasBaseGLES3::occluder_polygon_create() {
- return RID();
-}
-
-void RasterizerCanvasBaseGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
-}
-
-void RasterizerCanvasBaseGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
-}
-
-void RasterizerCanvasBaseGLES3::set_shadow_texture_size(int p_size) {
-}
-
-bool RasterizerCanvasBaseGLES3::free(RID p_rid) {
- return true;
-}
-
-void RasterizerCanvasBaseGLES3::update() {
-}
-
-void RasterizerCanvasBaseGLES3::canvas_begin() {
- state.using_transparent_rt = false;
-
- // always start with light_angle unset
- state.using_light_angle = false;
- state.using_large_vertex = false;
- state.using_modulate = false;
-
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, false);
- state.canvas_shader.bind();
-
- int viewport_x, viewport_y, viewport_width, viewport_height;
-
- if (storage->frame.current_rt) {
- storage->bind_framebuffer(storage->frame.current_rt->fbo);
- state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT];
-
- if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
- // set Viewport and Scissor when rendering directly to screen
- viewport_width = storage->_dims.rt_width;
- viewport_height = storage->_dims.rt_height;
- viewport_x = storage->frame.current_rt->x;
- // FTODO
- // viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
- viewport_y = storage->frame.current_rt->y;
-
- // viewport_x = 0;
- // viewport_y = 0;
-
- glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
- glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
- glEnable(GL_SCISSOR_TEST);
- }
- }
-
- // FTODO .. this was commented out to try and get the clear color correct
- //#ifdef GODOT3
- // OLD METHOD .. now done by render target rather than frame
-#if 0
- if (storage->frame.clear_request) {
- glClearColor(storage->frame.clear_request_color.r,
- storage->frame.clear_request_color.g,
- storage->frame.clear_request_color.b,
- state.using_transparent_rt ? storage->frame.clear_request_color.a : 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
- storage->frame.clear_request = false;
- }
-#endif
-
- // NEW METHOD
- if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) {
- const Color &col = storage->frame.current_rt->clear_color;
- glClearColor(col.r, col.g, col.b, col.a);
-
- // clear EVERYTHING.
- // not clearing everything can be devastating on tiled renderers especially,
- // because if anything is preserved, often the whole frame buffer needs to be preserved.
- // Not sure if GL_ACCUM_BUFFER_BIT is needed or supported in GLES.
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- storage->frame.current_rt->clear_requested = false;
- }
-
- //#endif
-
- /*
- if (storage->frame.current_rt) {
- glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
- glColorMask(1, 1, 1, 1);
- }
- */
-
- reset_canvas();
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
-
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
-
- // set up default uniforms
-
- Transform3D canvas_transform;
-
- if (storage->frame.current_rt) {
- float csy = 1.0;
- // FTODO
- // if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP]) {
- // csy = -1.0;
- // }
- canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f);
- canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f));
- } else {
- // FTODO
- // Vector2 ssize = OS::get_singleton()->get_window_size();
- Vector2 ssize;
- ssize.x = storage->_dims.win_width;
- ssize.y = storage->_dims.win_height;
-
- canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
- canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f));
- }
-
- state.uniforms.projection_matrix = canvas_transform;
-
- state.uniforms.final_modulate = Color(1, 1, 1, 1);
-
- state.uniforms.modelview_matrix = Transform2D();
- state.uniforms.extra_matrix = Transform2D();
-
- _set_uniforms();
- _bind_quad_buffer();
-
- glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_item_ubo);
- glBindVertexArray(data.canvas_quad_array);
-}
-
-void RasterizerCanvasBaseGLES3::canvas_end() {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
- //reset viewport to full window size
- // int viewport_width = OS::get_singleton()->get_window_size().width;
- // int viewport_height = OS::get_singleton()->get_window_size().height;
- int viewport_width = storage->_dims.win_width;
- int viewport_height = storage->_dims.win_height;
- glViewport(0, 0, viewport_width, viewport_height);
- glScissor(0, 0, viewport_width, viewport_height);
- }
-
- state.using_texture_rect = false;
- state.using_skeleton = false;
- state.using_ninepatch = false;
- state.using_transparent_rt = false;
-}
-
-void RasterizerCanvasBaseGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
- state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
- _bind_quad_buffer();
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-}
-
-void RasterizerCanvasBaseGLES3::_set_texture_rect_mode(bool p_texture_rect, bool p_light_angle, bool p_modulate, bool p_large_vertex) {
- // always set this directly (this could be state checked)
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_TEXTURE_RECT, p_texture_rect);
-
- if (state.using_light_angle != p_light_angle) {
- state.using_light_angle = p_light_angle;
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LIGHT_ANGLE, p_light_angle);
- }
-
- if (state.using_modulate != p_modulate) {
- state.using_modulate = p_modulate;
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_MODULATE, p_modulate);
- }
-
- if (state.using_large_vertex != p_large_vertex) {
- state.using_large_vertex = p_large_vertex;
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_ATTRIB_LARGE_VERTEX, p_large_vertex);
- }
-}
-
-RasterizerStorageGLES3::Texture *RasterizerCanvasBaseGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
- RasterizerStorageGLES3::Texture *tex_return = NULL;
-
- if (p_texture.is_valid()) {
- RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(p_texture);
-
- if (!texture) {
- state.current_tex = RID();
- state.current_tex_ptr = NULL;
-
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
-
- } else {
- if (texture->redraw_if_visible) {
- RenderingServerDefault::redraw_request();
- }
-
- texture = texture->get_ptr();
-
- if (texture->render_target) {
- texture->render_target->used_in_frame = true;
- }
-
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
-
- state.current_tex = p_texture;
- state.current_tex_ptr = texture;
-
- // new for Godot 4. Set the texture min mag filter and repeat per item
- // we use a wrapper to avoid noop GL state changes
- texture->GLSetFilter(GL_TEXTURE_2D, state.current_filter);
-
- tex_return = texture;
- }
- } else {
- state.current_tex = RID();
- state.current_tex_ptr = NULL;
-
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
- }
-
- if (p_normal_map == state.current_normal) {
- //do none
- state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
-
- } else if (p_normal_map.is_valid()) {
- RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(p_normal_map);
-
- if (!normal_map) {
- state.current_normal = RID();
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
- glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
-
- } else {
- if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
- RenderingServerDefault::redraw_request();
- }
-
- normal_map = normal_map->get_ptr();
-
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
- glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
- state.current_normal = p_normal_map;
- state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, true);
- }
-
- } else {
- state.current_normal = RID();
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
- glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
- }
-
- return tex_return;
-}
-
-/*
-void RasterizerCanvasBaseGLES3::draw_window_margins(int *black_margin, RID *black_image) {
- return;
-
- // FTODO
- int window_w = storage->_dims.rt_width;
- int window_h = storage->_dims.rt_height;
- //Vector2 window_size = Vector2(window_w, window_h);
-
- // int window_h = window_size.height;
- // int window_w = window_size.width;
-
- // glBindFramebuffer(GL_FRAMEBUFFER, storage->system_fbo);
- // glViewport(0, 0, window_size.width, window_size.height);
-
- canvas_begin();
-
- if (black_image[SIDE_LEFT].is_valid()) {
- _bind_canvas_texture(black_image[SIDE_LEFT], RID());
- Size2 sz(storage->texture_get_width(black_image[SIDE_LEFT]), storage->texture_get_height(black_image[SIDE_LEFT]));
- draw_generic_textured_rect(Rect2(0, 0, black_margin[SIDE_LEFT], window_h),
- Rect2(0, 0, (float)black_margin[SIDE_LEFT] / sz.x, (float)(window_h) / sz.y));
- } else if (black_margin[SIDE_LEFT]) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
-
- draw_generic_textured_rect(Rect2(0, 0, black_margin[SIDE_LEFT], window_h), Rect2(0, 0, 1, 1));
- }
-
- if (black_image[SIDE_RIGHT].is_valid()) {
- _bind_canvas_texture(black_image[SIDE_RIGHT], RID());
- Size2 sz(storage->texture_get_width(black_image[SIDE_RIGHT]), storage->texture_get_height(black_image[SIDE_RIGHT]));
- draw_generic_textured_rect(Rect2(window_w - black_margin[SIDE_RIGHT], 0, black_margin[SIDE_RIGHT], window_h),
- Rect2(0, 0, (float)black_margin[SIDE_RIGHT] / sz.x, (float)window_h / sz.y));
- } else if (black_margin[SIDE_RIGHT]) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
-
- draw_generic_textured_rect(Rect2(window_w - black_margin[SIDE_RIGHT], 0, black_margin[SIDE_RIGHT], window_h), Rect2(0, 0, 1, 1));
- }
-
- if (black_image[SIDE_TOP].is_valid()) {
- _bind_canvas_texture(black_image[SIDE_TOP], RID());
-
- Size2 sz(storage->texture_get_width(black_image[SIDE_TOP]), storage->texture_get_height(black_image[SIDE_TOP]));
- draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[SIDE_TOP]),
- Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[SIDE_TOP] / sz.y));
-
- } else if (black_margin[SIDE_TOP]) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
-
- draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[SIDE_TOP]), Rect2(0, 0, 1, 1));
- }
-
- if (black_image[SIDE_BOTTOM].is_valid()) {
- _bind_canvas_texture(black_image[SIDE_BOTTOM], RID());
-
- Size2 sz(storage->texture_get_width(black_image[SIDE_BOTTOM]), storage->texture_get_height(black_image[SIDE_BOTTOM]));
- draw_generic_textured_rect(Rect2(0, window_h - black_margin[SIDE_BOTTOM], window_w, black_margin[SIDE_BOTTOM]),
- Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[SIDE_BOTTOM] / sz.y));
-
- } else if (black_margin[SIDE_BOTTOM]) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
-
- draw_generic_textured_rect(Rect2(0, window_h - black_margin[SIDE_BOTTOM], window_w, black_margin[SIDE_BOTTOM]), Rect2(0, 0, 1, 1));
- }
-
- canvas_end();
-}
-*/
-
-void RasterizerCanvasBaseGLES3::_bind_quad_buffer() {
- glBindVertexArray(data.canvas_quad_array);
-}
-
-void RasterizerCanvasBaseGLES3::_set_uniforms() {
- state.canvas_shader.set_uniform(CanvasShaderGLES3::PROJECTION_MATRIX, state.uniforms.projection_matrix);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.uniforms.final_modulate);
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::TIME, storage->frame.time[0]);
-
- if (storage->frame.current_rt) {
- Vector2 screen_pixel_size;
- screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
- screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SCREEN_PIXEL_SIZE, screen_pixel_size);
- }
-
- if (state.using_skeleton) {
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM, state.skeleton_transform);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size);
- }
-
- if (state.using_light) {
- Light *light = state.using_light;
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX, light->light_shader_xform);
- Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
- basis_inverse.elements[2] = Vector2();
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_MATRIX_INVERSE, basis_inverse);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_COLOR, light->color * light->energy);
- // state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_pos);
- // FTODO
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_POS, light->light_shader_xform.elements[2]);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_HEIGHT, light->height);
-
- // FTODO
- //state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, light->mode == RS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_OUTSIDE_ALPHA, 0.0f);
-
- if (state.using_shadow) {
- // FTODO
-#if 0
- RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
- glBindTexture(GL_TEXTURE_2D, cls->distance);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_MATRIX, light->shadow_matrix_cache);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::LIGHT_SHADOW_COLOR, light->shadow_color);
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOWPIXEL_SIZE, (1.0 / light->shadow_buffer_size) * (1.0 + light->shadow_smooth));
- if (light->radius_cache == 0) {
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_GRADIENT, 0.0);
- } else {
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_GRADIENT, light->shadow_gradient_length / (light->radius_cache * 1.1));
- }
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SHADOW_DISTANCE_MULT, light->radius_cache * 1.1);
-#endif
- }
- }
-}
-
-void RasterizerCanvasBaseGLES3::reset_canvas() {
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_DITHER);
- glEnable(GL_BLEND);
-
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- // bind the back buffer to a texture so shaders can use it.
- // It should probably use texture unit -3 (as OpenGL does as well) but currently that's buggy.
- // keeping this for now as there's nothing else that uses texture unit 2
- // TODO ^
- if (storage->frame.current_rt) {
- // glActiveTexture(GL_TEXTURE0 + 2);
- // glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {
-}
-
-void RasterizerCanvasBaseGLES3::_copy_texscreen(const Rect2 &p_rect) {
- state.canvas_texscreen_used = true;
-
- _copy_screen(p_rect);
-
- // back to canvas, force rebind
- state.using_texture_rect = false;
- state.canvas_shader.bind();
- _bind_canvas_texture(state.current_tex, state.current_normal);
- _set_uniforms();
-}
-
-void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) {
- glBindVertexArray(data.polygon_buffer_pointer_array);
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
-
- uint32_t buffer_ofs = 0;
- uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
-#endif
-
- storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
-
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
- buffer_ofs = buffer_ofs_after;
-
- if (p_singlecolor) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- Color m = *p_colors;
- glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
- } else if (!p_colors) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
- } else {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- }
-
- if (p_uvs) {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- } else {
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
- }
-
- if (p_weights && p_bones) {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);
- glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
-
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_BONES);
- glVertexAttribPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
-
- } else {
- glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);
- glDisableVertexAttribArray(RS::ARRAY_BONES);
- }
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
-
- if (storage->config.support_32_bits_indices) { //should check for
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size);
-#endif
- storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
-
- glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0);
- storage->info.render._2d_draw_call_count++;
- } else {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size);
-#endif
- uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
- for (int i = 0; i < p_index_count; i++) {
- index16[i] = uint16_t(p_indices[i]);
- }
- storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(uint16_t) * p_index_count, index16, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
- glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_SHORT, 0);
- storage->info.render._2d_draw_call_count++;
- }
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
- glBindVertexArray(data.polygon_buffer_pointer_array);
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
-
- uint32_t buffer_ofs = 0;
- uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
-#endif
- storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
-
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
- buffer_ofs = buffer_ofs_after;
-
- if (p_singlecolor) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- Color m = *p_colors;
- glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
- } else if (!p_colors) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
- } else {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- }
-
- if (p_uvs) {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- } else {
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
- }
-
- glDrawArrays(p_primitive, 0, p_vertex_count);
- storage->info.render._2d_draw_call_count++;
-
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::_draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
- glBindVertexArray(data.polygon_buffer_pointer_array);
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
-
- uint32_t buffer_ofs = 0;
- uint32_t buffer_ofs_after = buffer_ofs + (sizeof(Vector2) * p_vertex_count);
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND(buffer_ofs_after > data.polygon_buffer_size);
-#endif
- storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
-
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
- buffer_ofs = buffer_ofs_after;
-
- if (p_singlecolor) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- Color m = *p_colors;
- glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
- } else if (!p_colors) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
- } else {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- }
-
- if (p_uvs) {
- RAST_FAIL_COND(!storage->safe_buffer_sub_data(data.polygon_buffer_size, GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs, buffer_ofs_after));
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
- buffer_ofs = buffer_ofs_after;
- } else {
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
- }
-
-#ifdef RASTERIZER_EXTRA_CHECKS
- // very slow, do not enable in normal use
- for (int n = 0; n < p_index_count; n++) {
- RAST_DEV_DEBUG_ASSERT(p_indices[n] < p_vertex_count);
- }
-#endif
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
-
- if (storage->config.support_32_bits_indices) { //should check for
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND((sizeof(int) * p_index_count) > data.polygon_index_buffer_size);
-#endif
- storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(int) * p_index_count, p_indices, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
- glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0);
- storage->info.render._2d_draw_call_count++;
- } else {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_COND((sizeof(uint16_t) * p_index_count) > data.polygon_index_buffer_size);
-#endif
- uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
- for (int i = 0; i < p_index_count; i++) {
- index16[i] = uint16_t(p_indices[i]);
- }
- storage->buffer_orphan_and_upload(data.polygon_index_buffer_size, 0, sizeof(uint16_t) * p_index_count, index16, GL_ELEMENT_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
- glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_SHORT, 0);
- storage->info.render._2d_draw_call_count++;
- }
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::_legacy_draw_poly_triangles(Item::CommandPolygon *p_poly, RasterizerStorageGLES3::Material *p_material) {
- // return;
-
- const PolyData &pd = _polydata[p_poly->polygon.polygon_id];
-
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- // FTODO
- //RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(p_poly->texture, RID());
-
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- }
-
- _draw_polygon(pd.indices.ptr(), pd.indices.size(), pd.points.size(), pd.points.ptr(), pd.uvs.ptr(), pd.colors.ptr(), pd.colors.size() == 1, nullptr, nullptr);
-
-// _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1, polygon->weights.ptr(), polygon->bones.ptr());
-#ifdef GLES_OVER_GL
-#if 0
- if (polygon->antialiased) {
- glEnable(GL_LINE_SMOOTH);
- if (polygon->antialiasing_use_indices) {
- _draw_generic_indices(GL_LINE_STRIP, polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
- } else {
- _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
- }
- glDisable(GL_LINE_SMOOTH);
- }
-#endif
-#endif
-}
-
-void RasterizerCanvasBaseGLES3::_legacy_draw_primitive(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material) {
- // return;
-
- if (p_pr->point_count != 4)
- return; // not sure if supported
-
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- _bind_canvas_texture(RID(), RID());
-
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
-
- _draw_gui_primitive(p_pr->point_count, p_pr->points, NULL, NULL);
-}
-
-void RasterizerCanvasBaseGLES3::_legacy_draw_line(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material) {
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- _bind_canvas_texture(RID(), RID());
-
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, p_pr->colors[0].components);
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
-
-#ifdef GLES_OVER_GL
-// if (line->antialiased)
-// glEnable(GL_LINE_SMOOTH);
-#endif
- _draw_gui_primitive(2, p_pr->points, NULL, NULL);
-
-#ifdef GLES_OVER_GL
-// if (line->antialiased)
-// glDisable(GL_LINE_SMOOTH);
-#endif
-}
-
-void RasterizerCanvasBaseGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const float *p_light_angles) {
- static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
-
- int version = 0;
- int color_offset = 0;
- int uv_offset = 0;
- int light_angle_offset = 0;
- int stride = 2;
-
- if (p_colors) {
- version |= 1;
- color_offset = stride;
- stride += 4;
- }
-
- if (p_uvs) {
- version |= 2;
- uv_offset = stride;
- stride += 2;
- }
-
- if (p_light_angles) { //light_angles
- version |= 4;
- light_angle_offset = stride;
- stride += 1;
- }
-
- RAST_DEV_DEBUG_ASSERT(p_points <= 4);
- float buffer_data[(2 + 2 + 4 + 1) * 4];
-
- for (int i = 0; i < p_points; i++) {
- buffer_data[stride * i + 0] = p_vertices[i].x;
- buffer_data[stride * i + 1] = p_vertices[i].y;
- }
-
- if (p_colors) {
- for (int i = 0; i < p_points; i++) {
- buffer_data[stride * i + color_offset + 0] = p_colors[i].r;
- buffer_data[stride * i + color_offset + 1] = p_colors[i].g;
- buffer_data[stride * i + color_offset + 2] = p_colors[i].b;
- buffer_data[stride * i + color_offset + 3] = p_colors[i].a;
- }
- }
-
- if (p_uvs) {
- for (int i = 0; i < p_points; i++) {
- buffer_data[stride * i + uv_offset + 0] = p_uvs[i].x;
- buffer_data[stride * i + uv_offset + 1] = p_uvs[i].y;
- }
- }
-
- if (p_light_angles) {
- for (int i = 0; i < p_points; i++) {
- buffer_data[stride * i + light_angle_offset + 0] = p_light_angles[i];
- }
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
- storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, p_points * stride * 4 * sizeof(float), buffer_data, GL_ARRAY_BUFFER, _buffer_upload_usage_flag, true);
-
- glBindVertexArray(data.polygon_buffer_quad_arrays[version]);
-
- glDrawArrays(prim[p_points], 0, p_points);
- storage->info.render._2d_draw_call_count++;
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::_copy_screen(const Rect2 &p_rect) {
- if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
- ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen.");
- return;
- }
-
- ERR_FAIL_COND_MSG(storage->frame.current_rt->copy_screen_effect.color == 0, "Can't use screen texture copying in a render target configured without copy buffers.");
-
- glDisable(GL_BLEND);
-
- Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height);
-
- Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y);
-
- if (p_rect != Rect2()) {
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, true);
- }
-
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_NO_ALPHA, !state.using_transparent_rt);
-
- storage->bind_framebuffer(storage->frame.current_rt->copy_screen_effect.fbo);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
-
- storage->shaders.copy.bind();
- storage->shaders.copy.set_uniform(CopyShaderGLES3::COPY_SECTION, copy_section);
-
- const Vector2 vertpos[4] = {
- Vector2(-1, -1),
- Vector2(-1, 1),
- Vector2(1, 1),
- Vector2(1, -1),
- };
-
- const Vector2 uvpos[4] = {
- Vector2(0, 0),
- Vector2(0, 1),
- Vector2(1, 1),
- Vector2(1, 0)
- };
-
- const int indexpos[6] = {
- 0, 1, 2,
- 2, 3, 0
- };
-
- _draw_polygon(indexpos, 6, 4, vertpos, uvpos, NULL, false);
-
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_COPY_SECTION, false);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_NO_ALPHA, false);
-
- storage->bind_framebuffer(storage->frame.current_rt->fbo);
- glEnable(GL_BLEND);
-}
-
-void RasterizerCanvasBaseGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
-#if 0
- RasterizerStorageGLES3::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(p_buffer);
- ERR_FAIL_COND(!cls);
-
- glDisable(GL_BLEND);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_DITHER);
- glDisable(GL_CULL_FACE);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(true);
-
- glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
-
- state.canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
- state.canvas_shadow_shader.bind();
-
- glViewport(0, 0, cls->size, cls->height);
- glClearDepth(1.0f);
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- RS::CanvasOccluderPolygonCullMode cull = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
-
- for (int i = 0; i < 4; i++) {
- //make sure it remains orthogonal, makes easy to read angle later
-
- Transform3D light;
- light.origin[0] = p_light_xform[2][0];
- light.origin[1] = p_light_xform[2][1];
- light.basis[0][0] = p_light_xform[0][0];
- light.basis[0][1] = p_light_xform[1][0];
- light.basis[1][0] = p_light_xform[0][1];
- light.basis[1][1] = p_light_xform[1][1];
-
- //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
-
- //p_near=1;
- CameraMatrix projection;
- {
- real_t fov = 90;
- real_t nearp = p_near;
- real_t farp = p_far;
- real_t aspect = 1.0;
-
- real_t ymax = nearp * Math::tan(Math::deg2rad(fov * 0.5));
- real_t ymin = -ymax;
- real_t xmin = ymin * aspect;
- real_t xmax = ymax * aspect;
-
- projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
- }
-
- Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * (i / 4.0))).xform(Vector3(0, 1, 0));
- projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
-
- state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::PROJECTION_MATRIX, projection);
- state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::LIGHT_MATRIX, light);
- state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::DISTANCE_NORM, 1.0 / p_far);
-
- if (i == 0)
- *p_xform_cache = projection;
-
- glViewport(0, (cls->height / 4) * i, cls->size, cls->height / 4);
-
- LightOccluderInstance *instance = p_occluders;
-
- while (instance) {
- RasterizerStorageGLES3::CanvasOccluder *cc = storage->canvas_occluder_owner.get_or_null(instance->polygon_buffer);
- if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
- instance = instance->next;
- continue;
- }
-
- state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES3::WORLD_MATRIX, instance->xform_cache);
-
- RS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache;
-
- if (transformed_cull_cache != RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED &&
- (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) {
- transformed_cull_cache =
- transformed_cull_cache == RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ?
- RS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE :
- RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE;
- }
-
- if (cull != transformed_cull_cache) {
- cull = transformed_cull_cache;
- switch (cull) {
- case RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
- glDisable(GL_CULL_FACE);
-
- } break;
- case RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_FRONT);
- } break;
- case RS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
- } break;
- }
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id);
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id);
-
- glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0);
-
- instance = instance->next;
- }
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-#endif
-}
-
-void RasterizerCanvasBaseGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
- Vector2 half_size;
- if (storage->frame.current_rt) {
- half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height);
- } else {
- // half_size = OS::get_singleton()->get_window_size();
- half_size = Vector2(storage->_dims.win_width, storage->_dims.win_height);
- }
- half_size *= 0.5;
- Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y);
- Vector2 scale(p_rect.size.x / half_size.x, p_rect.size.y / half_size.y);
-
- float aspect_ratio = p_rect.size.x / p_rect.size.y;
-
- // setup our lens shader
- state.lens_shader.bind();
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::OFFSET, offset);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::SCALE, scale);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::K1, p_k1);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::K2, p_k2);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::EYE_CENTER, p_eye_center);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::UPSCALE, p_oversample);
- state.lens_shader.set_uniform(LensDistortedShaderGLES3::ASPECT_RATIO, aspect_ratio);
-
- // bind our quad buffer
- _bind_quad_buffer();
-
- // and draw
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- // and cleanup
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-}
-
-void RasterizerCanvasBaseGLES3::initialize() {
- bool flag_stream = false;
- //flag_stream = GLOBAL_GET("rendering/options/api_usage_legacy/flag_stream");
- if (flag_stream)
- _buffer_upload_usage_flag = GL_STREAM_DRAW;
- else
- _buffer_upload_usage_flag = GL_DYNAMIC_DRAW;
-
- // quad buffer
- {
- glGenBuffers(1, &data.canvas_quad_vertices);
- glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
-
- const float qv[8] = {
- 0, 0,
- 0, 1,
- 1, 1,
- 1, 0
- };
-
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glGenVertexArrays(1, &data.canvas_quad_array);
- glBindVertexArray(data.canvas_quad_array);
- glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
- glEnableVertexAttribArray(0);
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- }
-
- {
- //particle quad buffers
-
- glGenBuffers(1, &data.particle_quad_vertices);
- glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
- {
- //quad of size 1, with pivot on the center for particles, then regular UVS. Color is general plus fetched from particle
- const float qv[16] = {
- -0.5, -0.5,
- 0.0, 0.0,
- -0.5, 0.5,
- 0.0, 1.0,
- 0.5, 0.5,
- 1.0, 1.0,
- 0.5, -0.5,
- 1.0, 0.0
- };
-
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW);
- }
-
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
-
- glGenVertexArrays(1, &data.particle_quad_array);
- glBindVertexArray(data.particle_quad_array);
- glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr);
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8));
- glBindVertexArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- }
-
- // polygon buffer
- {
- uint32_t poly_size = 128; //GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
- poly_size = MAX(poly_size, 2); // minimum 2k, may still see anomalies in editor
- poly_size *= 1024; //kb
- glGenBuffers(1, &data.polygon_buffer);
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
- glBufferData(GL_ARRAY_BUFFER, poly_size, nullptr, GL_DYNAMIC_DRAW); //allocate max size
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- data.polygon_buffer_size = poly_size;
-
- //quad arrays
- for (int i = 0; i < Data::NUM_QUAD_ARRAY_VARIATIONS; i++) {
- glGenVertexArrays(1, &data.polygon_buffer_quad_arrays[i]);
- glBindVertexArray(data.polygon_buffer_quad_arrays[i]);
- glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
-
- int uv_ofs = 0;
- int color_ofs = 0;
- int light_angle_ofs = 0;
- int stride = 2 * 4;
-
- if (i & 1) { //color
- color_ofs = stride;
- stride += 4 * 4;
- }
-
- if (i & 2) { //uv
- uv_ofs = stride;
- stride += 2 * 4;
- }
-
- if (i & 4) { //light_angle
- light_angle_ofs = stride;
- stride += 1 * 4;
- }
-
- glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride, nullptr);
-
- if (i & 1) {
- glEnableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(color_ofs));
- }
-
- if (i & 2) {
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(uv_ofs));
- }
-
- if (i & 4) {
- // reusing tangent for light_angle
- glEnableVertexAttribArray(RS::ARRAY_TANGENT);
- glVertexAttribPointer(RS::ARRAY_TANGENT, 1, GL_FLOAT, GL_FALSE, stride, CAST_INT_TO_UCHAR_PTR(light_angle_ofs));
- }
-
- glBindVertexArray(0);
- }
-
- glGenVertexArrays(1, &data.polygon_buffer_pointer_array);
-
- uint32_t index_size = 128; //GLOBAL_DEF_RST("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
- index_size = MAX(index_size, 2);
- index_size *= 1024; //kb
- glGenBuffers(1, &data.polygon_index_buffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, nullptr, GL_DYNAMIC_DRAW); //allocate max size
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
- data.polygon_index_buffer_size = index_size;
- }
-
- // ninepatch buffers
- {
- // array buffer
- glGenBuffers(1, &data.ninepatch_vertices);
- glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
-
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- // element buffer
- glGenBuffers(1, &data.ninepatch_elements);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
-
-#define _EIDX(y, x) (y * 4 + x)
- uint8_t elems[3 * 2 * 9] = {
- // first row
-
- _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1),
- _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0),
-
- _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2),
- _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1),
-
- _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3),
- _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2),
-
- // second row
-
- _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1),
- _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0),
-
- // the center one would be here, but we'll put it at the end
- // so it's easier to disable the center and be able to use
- // one draw call for both
-
- _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3),
- _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2),
-
- // third row
-
- _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1),
- _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0),
-
- _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2),
- _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1),
-
- _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3),
- _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2),
-
- // center field
-
- _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2),
- _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1)
- };
-#undef _EIDX
-
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
-
- store_transform3d(Transform3D(), state.canvas_item_ubo_data.projection_matrix);
-
- glGenBuffers(1, &state.canvas_item_ubo);
- glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo);
- glBufferData(GL_UNIFORM_BUFFER, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-
- state.canvas_shadow_shader.init();
- state.canvas_shader.init();
- _set_texture_rect_mode(true);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
-
- state.canvas_shader.bind();
-
- state.lens_shader.init();
-
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
-
- state.using_light = NULL;
- state.using_transparent_rt = false;
- state.using_skeleton = false;
-}
-
-RendererCanvasRender::PolygonID RasterizerCanvasBaseGLES3::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
- uint32_t id = _polydata.alloc();
- PolyData &pd = _polydata[id];
- pd.indices = p_indices;
- pd.points = p_points;
- pd.colors = p_colors;
- pd.uvs = p_uvs;
- return id;
-}
-void RasterizerCanvasBaseGLES3::free_polygon(PolygonID p_polygon) {
- _polydata.free(p_polygon);
-}
-
-void RasterizerCanvasBaseGLES3::finalize() {
- glDeleteBuffers(1, &data.canvas_quad_vertices);
- glDeleteVertexArrays(1, &data.canvas_quad_array);
-
- glDeleteBuffers(1, &data.canvas_quad_vertices);
- glDeleteVertexArrays(1, &data.canvas_quad_array);
-
- glDeleteVertexArrays(1, &data.polygon_buffer_pointer_array);
-}
-
-RasterizerCanvasBaseGLES3::RasterizerCanvasBaseGLES3() {
-}
-
-#endif // GLES3_BACKEND_ENABLED
diff --git a/drivers/gles3/rasterizer_canvas_base_gles3.h b/drivers/gles3/rasterizer_canvas_base_gles3.h
deleted file mode 100644
index 60292ff875..0000000000
--- a/drivers/gles3/rasterizer_canvas_base_gles3.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*************************************************************************/
-/* rasterizer_canvas_base_gles3.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 RASTERIZER_CANVAS_BASE_OPENGL_H
-#define RASTERIZER_CANVAS_BASE_OPENGL_H
-
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
-
-#include "drivers/gles3/rasterizer_array.h"
-#include "drivers/gles3/rasterizer_storage_common.h"
-#include "rasterizer_scene_gles3.h"
-#include "rasterizer_storage_gles3.h"
-#include "servers/rendering/renderer_canvas_render.h"
-#include "servers/rendering/renderer_compositor.h"
-
-#include "shaders/canvas.glsl.gen.h"
-#include "shaders/canvas_shadow.glsl.gen.h"
-#include "shaders/lens_distorted.glsl.gen.h"
-
-class RasterizerCanvasBaseGLES3 : public RendererCanvasRender {
-public:
- enum {
- INSTANCE_ATTRIB_BASE = 8,
- };
-
- struct Uniforms {
- Transform3D projection_matrix;
-
- Transform2D modelview_matrix;
- Transform2D extra_matrix;
-
- Color final_modulate;
-
- float time;
- };
-
- struct CanvasItemUBO {
- float projection_matrix[16];
- float time;
- uint8_t padding[12];
- };
-
- struct Data {
- enum { NUM_QUAD_ARRAY_VARIATIONS = 8 };
-
- GLuint canvas_quad_vertices;
- GLuint canvas_quad_array;
-
- GLuint polygon_buffer;
- GLuint polygon_buffer_quad_arrays[NUM_QUAD_ARRAY_VARIATIONS];
- GLuint polygon_buffer_pointer_array;
- GLuint polygon_index_buffer;
-
- GLuint particle_quad_vertices;
- GLuint particle_quad_array;
-
- uint32_t polygon_buffer_size;
- uint32_t polygon_index_buffer_size;
-
- GLuint ninepatch_vertices;
- GLuint ninepatch_elements;
- } data;
-
- struct State {
- Uniforms uniforms;
- CanvasItemUBO canvas_item_ubo_data;
- GLuint canvas_item_ubo;
- bool canvas_texscreen_used;
- CanvasShaderGLES3 canvas_shader;
- CanvasShadowShaderGLES3 canvas_shadow_shader;
- LensDistortedShaderGLES3 lens_shader;
-
- bool using_texture_rect;
-
- bool using_light_angle;
- bool using_modulate;
- bool using_large_vertex;
-
- bool using_ninepatch;
- bool using_skeleton;
-
- Transform2D skeleton_transform;
- Transform2D skeleton_transform_inverse;
- Size2i skeleton_texture_size;
-
- RID current_tex;
- RID current_normal;
- RasterizerStorageGLES3::Texture *current_tex_ptr;
-
- Transform3D vp;
- Light *using_light;
- bool using_shadow;
- bool using_transparent_rt;
-
- // new for Godot 4.0
- // min mag filter is per item, and repeat
- RS::CanvasItemTextureFilter current_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
- RS::CanvasItemTextureRepeat current_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
- } state;
-
- typedef void Texture;
-
- RasterizerSceneGLES3 *scene_render;
-
- RasterizerStorageGLES3 *storage;
-
- // allow user to choose api usage
- GLenum _buffer_upload_usage_flag;
-
- void _set_uniforms();
-
- virtual RID light_internal_create();
- virtual void light_internal_update(RID p_rid, Light *p_light);
- virtual void light_internal_free(RID p_rid);
-
- virtual void canvas_begin();
- virtual void canvas_end();
-
-protected:
- void _legacy_draw_primitive(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material);
- void _legacy_draw_line(Item::CommandPrimitive *p_pr, RasterizerStorageGLES3::Material *p_material);
- void _legacy_draw_poly_triangles(Item::CommandPolygon *p_poly, RasterizerStorageGLES3::Material *p_material);
-
-public:
- void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const float *p_light_angles = nullptr);
- void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = NULL, const int *p_bones = NULL);
- void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
- void _draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
-
- void _bind_quad_buffer();
- void _copy_texscreen(const Rect2 &p_rect);
- void _copy_screen(const Rect2 &p_rect);
-
- //virtual void draw_window_margins(int *black_margin, RID *black_image) override;
- void draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src);
- void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
-
- virtual void reset_canvas();
- virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
-
- // Copied from RasterizerCanvasDummy:
- virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override;
-
- RID light_create() override;
- void light_set_texture(RID p_rid, RID p_texture) override;
- void light_set_use_shadow(RID p_rid, bool p_enable) override;
- void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override;
- void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override;
-
- void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override;
- RID occluder_polygon_create() override;
- void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override;
- void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override;
- void set_shadow_texture_size(int p_size) override;
-
- bool free(RID p_rid) override;
- void update() override;
- // End copied from RasterizerCanvasDummy.
-
- RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
- void _set_texture_rect_mode(bool p_texture_rect, bool p_light_angle = false, bool p_modulate = false, bool p_large_vertex = false);
-
- // NEW API
- struct PolyData {
- LocalVector<int> indices;
- LocalVector<Point2> points;
- LocalVector<Color> colors;
- LocalVector<Point2> uvs;
- };
-
- RendererCanvasRender::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;
- void free_polygon(PolygonID p_polygon) override;
-
- RasterizerPooledIndirectList<PolyData> _polydata;
-
- //////////////////////
- void initialize();
- void finalize();
-
- RasterizerCanvasBaseGLES3();
-};
-
-#endif // GLES3_BACKEND_ENABLED
-
-#endif // RASTERIZER_CANVAS_BASE_OPENGL_H
diff --git a/drivers/gles3/rasterizer_canvas_batcher.h b/drivers/gles3/rasterizer_canvas_batcher.h
deleted file mode 100644
index c505d46859..0000000000
--- a/drivers/gles3/rasterizer_canvas_batcher.h
+++ /dev/null
@@ -1,1560 +0,0 @@
-/*************************************************************************/
-/* rasterizer_canvas_batcher.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 RASTERIZER_CANVAS_BATCHER_H
-#define RASTERIZER_CANVAS_BATCHER_H
-
-#include "core/os/os.h"
-#include "core/templates/local_vector.h"
-#include "rasterizer_array.h"
-#include "rasterizer_asserts.h"
-#include "rasterizer_storage_common.h"
-
-#include "core/config/project_settings.h"
-#include "servers/rendering/renderer_compositor.h"
-
-// We are using the curiously recurring template pattern
-// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
-// For static polymorphism.
-
-// This makes it super easy to access
-// data / call funcs in the derived rasterizers from the base without writing and
-// maintaining a boatload of virtual functions.
-// In addition it assures that vtable will not be used and the function calls can be optimized,
-// because it gives compile time static polymorphism.
-
-// These macros makes it simpler and less verbose to define (and redefine) the inline functions
-// template preamble
-#define T_PREAMBLE template <class T, typename T_STORAGE>
-// class preamble
-#define C_PREAMBLE RasterizerCanvasBatcher<T, T_STORAGE>
-// generic preamble
-#define PREAMBLE(RET_T) \
- T_PREAMBLE \
- RET_T C_PREAMBLE
-
-template <class T, typename T_STORAGE>
-class RasterizerCanvasBatcher {
-public:
- // used to determine whether we use hardware transform (none)
- // software transform all verts, or software transform just a translate
- // (no rotate or scale)
- enum TransformMode {
- TM_NONE,
- TM_ALL,
- TM_TRANSLATE,
- };
-
- // pod versions of vector and color and RID, need to be 32 bit for vertex format
- struct BatchVector2 {
- float x, y;
- void set(float xx, float yy) {
- x = xx;
- y = yy;
- }
- void set(const Vector2 &p_o) {
- x = p_o.x;
- y = p_o.y;
- }
- void to(Vector2 &r_o) const {
- r_o.x = x;
- r_o.y = y;
- }
- };
-
- struct BatchColor {
- float r, g, b, a;
- void set_white() {
- r = 1.0f;
- g = 1.0f;
- b = 1.0f;
- a = 1.0f;
- }
- void set(const Color &p_c) {
- r = p_c.r;
- g = p_c.g;
- b = p_c.b;
- a = p_c.a;
- }
- void set(float rr, float gg, float bb, float aa) {
- r = rr;
- g = gg;
- b = bb;
- a = aa;
- }
- bool operator==(const BatchColor &p_c) const {
- return (r == p_c.r) && (g == p_c.g) && (b == p_c.b) && (a == p_c.a);
- }
- bool operator!=(const BatchColor &p_c) const { return (*this == p_c) == false; }
- bool equals(const Color &p_c) const {
- return (r == p_c.r) && (g == p_c.g) && (b == p_c.b) && (a == p_c.a);
- }
- const float *get_data() const { return &r; }
- String to_string() const {
- String sz = "{";
- const float *data = get_data();
- for (int c = 0; c < 4; c++) {
- float f = data[c];
- int val = ((f * 255.0f) + 0.5f);
- sz += String(Variant(val)) + " ";
- }
- sz += "}";
- return sz;
- }
- };
-
- // simplest FVF - local or baked position
- struct BatchVertex {
- // must be 32 bit pod
- BatchVector2 pos;
- BatchVector2 uv;
- };
-
- // simple FVF but also incorporating baked color
- struct BatchVertexColored : public BatchVertex {
- // must be 32 bit pod
- BatchColor col;
- };
-
- // if we are using normal mapping, we need light angles to be sent
- struct BatchVertexLightAngled : public BatchVertexColored {
- // must be pod
- float light_angle;
- };
-
- // CUSTOM SHADER vertex formats. These are larger but will probably
- // be needed with custom shaders in order to have the data accessible in the shader.
-
- // if we are using COLOR in vertex shader but not position (VERTEX)
- struct BatchVertexModulated : public BatchVertexLightAngled {
- BatchColor modulate;
- };
-
- struct BatchTransform {
- BatchVector2 translate;
- BatchVector2 basis[2];
- };
-
- // last resort, specially for custom shader, we put everything possible into a huge FVF
- // not very efficient, but better than no batching at all.
- struct BatchVertexLarge : public BatchVertexModulated {
- // must be pod
- BatchTransform transform;
- };
-
- // Batch should be as small as possible, and ideally nicely aligned (is 32 bytes at the moment)
- struct Batch {
- RasterizerStorageCommon::BatchType type; // should be 16 bit
- uint16_t batch_texture_id;
-
- // also item reference number
- uint32_t first_command;
-
- // in the case of DEFAULT, this is num commands.
- // with rects, is number of command and rects.
- // with lines, is number of lines
- uint32_t num_commands;
-
- // first vertex of this batch in the vertex lists
- uint32_t first_vert;
-
- BatchColor color;
- };
-
- struct BatchTex {
- enum TileMode : uint32_t {
- TILE_OFF,
- TILE_NORMAL,
- TILE_FORCE_REPEAT,
- };
- RID RID_texture;
- RID RID_normal;
- TileMode tile_mode;
- BatchVector2 tex_pixel_size;
- uint32_t flags;
- };
-
- // items in a list to be sorted prior to joining
- struct BSortItem {
- // have a function to keep as pod, rather than operator
- void assign(const BSortItem &o) {
- item = o.item;
- z_index = o.z_index;
- }
- RendererCanvasRender::Item *item;
- int z_index;
- };
-
- // batch item may represent 1 or more items
- struct BItemJoined {
- uint32_t first_item_ref;
- uint32_t num_item_refs;
-
- Rect2 bounding_rect;
-
- // note the z_index may only be correct for the first of the joined item references
- // this has implications for light culling with z ranged lights.
- int16_t z_index;
-
- // these are defined in RasterizerStorageCommon::BatchFlags
- uint16_t flags;
-
- // we are always splitting items with lots of commands,
- // and items with unhandled primitives (default)
- bool use_hardware_transform() const { return num_item_refs == 1; }
- };
-
- struct BItemRef {
- RendererCanvasRender::Item *item;
- Color final_modulate;
- };
-
- struct BLightRegion {
- void reset() {
- light_bitfield = 0;
- shadow_bitfield = 0;
- too_many_lights = false;
- }
- uint64_t light_bitfield;
- uint64_t shadow_bitfield;
- bool too_many_lights; // we can only do light region optimization if there are 64 or less lights
- };
-
- struct BatchData {
- BatchData() {
- reset_flush();
- reset_joined_item();
-
- gl_vertex_buffer = 0;
- gl_index_buffer = 0;
- max_quads = 0;
- vertex_buffer_size_units = 0;
- vertex_buffer_size_bytes = 0;
- index_buffer_size_units = 0;
- index_buffer_size_bytes = 0;
-
- use_colored_vertices = false;
-
- settings_use_batching = false;
- settings_max_join_item_commands = 0;
- settings_colored_vertex_format_threshold = 0.0f;
- settings_batch_buffer_num_verts = 0;
- scissor_threshold_area = 0.0f;
- joined_item_batch_flags = 0;
- diagnose_frame = false;
- next_diagnose_tick = 10000;
- diagnose_frame_number = 9999999999; // some high number
- join_across_z_indices = true;
- settings_item_reordering_lookahead = 0;
-
- settings_use_batching_original_choice = false;
- settings_flash_batching = false;
- settings_diagnose_frame = false;
- settings_scissor_lights = false;
- settings_scissor_threshold = -1.0f;
- settings_use_single_rect_fallback = false;
- settings_use_software_skinning = true;
- settings_ninepatch_mode = 0; // default
- settings_light_max_join_items = 16;
-
- settings_uv_contract = false;
- settings_uv_contract_amount = 0.0f;
-
- buffer_mode_batch_upload_send_null = true;
- buffer_mode_batch_upload_flag_stream = false;
-
- stats_items_sorted = 0;
- stats_light_items_joined = 0;
- }
-
- // called for each joined item
- void reset_joined_item() {
- // noop but left in as a stub
- }
-
- // called after each flush
- void reset_flush() {
- batches.reset();
- batch_textures.reset();
-
- vertices.reset();
- light_angles.reset();
- vertex_colors.reset();
- vertex_modulates.reset();
- vertex_transforms.reset();
-
- total_quads = 0;
- total_verts = 0;
- total_color_changes = 0;
-
- use_light_angles = false;
- use_modulate = false;
- use_large_verts = false;
- fvf = RasterizerStorageCommon::FVF_REGULAR;
- }
-
- unsigned int gl_vertex_buffer;
- unsigned int gl_index_buffer;
-
- uint32_t max_quads;
- uint32_t vertex_buffer_size_units;
- uint32_t vertex_buffer_size_bytes;
- uint32_t index_buffer_size_units;
- uint32_t index_buffer_size_bytes;
-
- // small vertex FVF type - pos and UV.
- // This will always be written to initially, but can be translated
- // to larger FVFs if necessary.
- RasterizerArray<BatchVertex> vertices;
-
- // extra data which can be stored during prefilling, for later translation to larger FVFs
- RasterizerArray<float> light_angles;
- RasterizerArray<BatchColor> vertex_colors; // these aren't usually used, but are for polys
- RasterizerArray<BatchColor> vertex_modulates;
- RasterizerArray<BatchTransform> vertex_transforms;
-
- // instead of having a different buffer for each vertex FVF type
- // we have a special array big enough for the biggest FVF
- // which can have a changeable unit size, and reuse it.
- RasterizerUnitArray unit_vertices;
-
- RasterizerArray<Batch> batches;
- RasterizerArray<Batch> batches_temp; // used for translating to colored vertex batches
- RasterizerArray_non_pod<BatchTex> batch_textures; // the only reason this is non-POD is because of RIDs
-
- // SHOULD THESE BE IN FILLSTATE?
- // flexible vertex format.
- // all verts have pos and UV.
- // some have color, some light angles etc.
- RasterizerStorageCommon::FVF fvf;
- bool use_colored_vertices;
- bool use_light_angles;
- bool use_modulate;
- bool use_large_verts;
-
- // if the shader is using MODULATE, we prevent baking color so the final_modulate can
- // be read in the shader.
- // if the shader is reading VERTEX, we prevent baking vertex positions with extra matrices etc
- // to prevent the read position being incorrect.
- // These flags are defined in RasterizerStorageCommon::BatchFlags
- uint32_t joined_item_batch_flags;
-
- RasterizerArray<BItemJoined> items_joined;
- RasterizerArray<BItemRef> item_refs;
-
- // items are sorted prior to joining
- RasterizerArray<BSortItem> sort_items;
-
- // new for Godot 4 .. the client outputs a linked list so we need to convert this
- // to a linear array
- LocalVector<RendererCanvasRender::Item::Command *> command_shortlist;
-
- // counts
- int total_quads;
- int total_verts;
-
- // we keep a record of how many color changes caused new batches
- // if the colors are causing an excessive number of batches, we switch
- // to alternate batching method and add color to the vertex format.
- int total_color_changes;
-
- // measured in pixels, recalculated each frame
- float scissor_threshold_area;
-
- // diagnose this frame, every nTh frame when settings_diagnose_frame is on
- bool diagnose_frame;
- String frame_string;
- uint32_t next_diagnose_tick;
- uint64_t diagnose_frame_number;
-
- // whether to join items across z_indices - this can interfere with z ranged lights,
- // so has to be disabled in some circumstances
- bool join_across_z_indices;
-
- // global settings
- bool settings_use_batching; // the current use_batching (affected by flash)
- bool settings_use_batching_original_choice; // the choice entered in project settings
- bool settings_flash_batching; // for regression testing, flash between non-batched and batched renderer
- bool settings_diagnose_frame; // print out batches to help optimize / regression test
- int settings_max_join_item_commands;
- float settings_colored_vertex_format_threshold;
- int settings_batch_buffer_num_verts;
- bool settings_scissor_lights;
- float settings_scissor_threshold; // 0.0 to 1.0
- int settings_item_reordering_lookahead;
- bool settings_use_single_rect_fallback;
- bool settings_use_software_skinning;
- int settings_light_max_join_items;
- int settings_ninepatch_mode;
-
- // buffer orphaning modes
- bool buffer_mode_batch_upload_send_null;
- bool buffer_mode_batch_upload_flag_stream;
-
- // uv contraction
- bool settings_uv_contract;
- float settings_uv_contract_amount;
-
- // only done on diagnose frame
- void reset_stats() {
- stats_items_sorted = 0;
- stats_light_items_joined = 0;
- }
-
- // frame stats (just for monitoring and debugging)
- int stats_items_sorted;
- int stats_light_items_joined;
- } bdata;
-
- struct FillState {
- void reset_flush() {
- // don't reset members that need to be preserved after flushing
- // half way through a list of commands
- curr_batch = 0;
- batch_tex_id = -1;
- texpixel_size = Vector2(1, 1);
- contract_uvs = false;
-
- sequence_batch_type_flags = 0;
- }
-
- void reset_joined_item(bool p_use_hardware_transform) {
- reset_flush();
- use_hardware_transform = p_use_hardware_transform;
- extra_matrix_sent = false;
- }
-
- // for batching multiple types, we don't allow mixing RECTs / LINEs etc.
- // using flags allows quicker rejection of sequences with different batch types
- uint32_t sequence_batch_type_flags;
-
- Batch *curr_batch;
- int batch_tex_id;
- bool use_hardware_transform;
- bool contract_uvs;
- Vector2 texpixel_size;
- Color final_modulate;
- TransformMode transform_mode;
- TransformMode orig_transform_mode;
-
- // support for extra matrices
- bool extra_matrix_sent; // whether sent on this item (in which case software transform can't be used untl end of item)
- int transform_extra_command_number_p1; // plus one to allow fast checking against zero
- Transform2D transform_combined; // final * extra
- };
-
- // used during try_join
- struct RenderItemState {
- RenderItemState() { reset(); }
- void reset() {
- current_clip = nullptr;
- shader_cache = nullptr;
- rebind_shader = true;
- prev_use_skeleton = false;
- last_blend_mode = -1;
- canvas_last_material = RID();
- item_group_z = 0;
- item_group_light = nullptr;
- final_modulate = Color(-1.0, -1.0, -1.0, -1.0); // just something unlikely
-
- joined_item_batch_type_flags_curr = 0;
- joined_item_batch_type_flags_prev = 0;
-
- joined_item = nullptr;
- }
-
- RendererCanvasRender::Item *current_clip;
- typename T_STORAGE::Shader *shader_cache;
- bool rebind_shader;
- bool prev_use_skeleton;
- bool prev_distance_field;
- int last_blend_mode;
- RID canvas_last_material;
- Color final_modulate;
-
- // used for joining items only
- BItemJoined *joined_item;
- bool join_batch_break;
- BLightRegion light_region;
-
- // we need some logic to prevent joining items that have vastly different batch types
- // these are defined in RasterizerStorageCommon::BatchTypeFlags
- uint32_t joined_item_batch_type_flags_curr;
- uint32_t joined_item_batch_type_flags_prev;
-
- // 'item group' is data over a single call to canvas_render_items
- int item_group_z;
- Color item_group_modulate;
- RendererCanvasRender::Light *item_group_light;
- Transform2D item_group_base_transform;
- } _render_item_state;
-
- bool use_nvidia_rect_workaround;
-
- //////////////////////////////////////////////////////////////////////////////
- // End of structs used by the batcher. Beginning of funcs.
-private:
- // curiously recurring template pattern - allows access to functions in the DERIVED class
- // this is kind of like using virtual functions but more efficient as they are resolved at compile time
- T_STORAGE *get_storage() { return static_cast<const T *>(this)->storage; }
- const T_STORAGE *get_storage() const { return static_cast<const T *>(this)->storage; }
- T *get_this() { return static_cast<T *>(this); }
- const T *get_this() const { return static_cast<const T *>(this); }
-
-protected:
- // main functions called from the rasterizer canvas
- void batch_constructor();
- void batch_initialize();
-
- void batch_canvas_begin();
- void batch_canvas_end();
- void batch_canvas_render_items_begin(const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform);
- void batch_canvas_render_items_end();
- void batch_canvas_render_items(RendererCanvasRender::Item *p_item_list, int p_z, const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform);
-
- // recording and sorting items from the initial pass
- void record_items(RendererCanvasRender::Item *p_item_list, int p_z);
- void join_sorted_items();
- void sort_items();
- bool _sort_items_match(const BSortItem &p_a, const BSortItem &p_b) const;
- bool sort_items_from(int p_start);
-
- // joining logic
- bool _disallow_item_join_if_batch_types_too_different(RenderItemState &r_ris, uint32_t btf_allowed);
- bool _detect_item_batch_break(RenderItemState &r_ris, RendererCanvasRender::Item *p_ci, bool &r_batch_break);
-
- // drives the loop filling batches and flushing
- void render_joined_item_commands(const BItemJoined &p_bij, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit);
-
-private:
- // flush once full or end of joined item
- void flush_render_batches(RendererCanvasRender::Item *p_first_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, uint32_t p_sequence_batch_type_flags);
-
- // a single joined item can contain multiple itemrefs, and thus create lots of batches
- // command start given a separate name to make easier to tell apart godot 3 and 4
- bool prefill_joined_item(FillState &r_fill_state, RendererCanvasRender::Item::Command **r_first_command, RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material);
-
- // prefilling different types of batch
-
- // default batch is an 'unhandled' legacy type batch that will be drawn with the legacy path,
- // all other batches are accelerated.
- void _prefill_default_batch(FillState &r_fill_state, int p_command_num, const RendererCanvasRender::Item &p_item);
-
- // accelerated batches
- bool _prefill_rect(RendererCanvasRender::Item::CommandRect *rect, FillState &r_fill_state, int &r_command_start, int command_num, int command_count, RendererCanvasRender::Item::Command *const *commands, RendererCanvasRender::Item *p_item, bool multiply_final_modulate);
-
- // dealing with textures
- int _batch_find_or_create_tex(const RID &p_texture, const RID &p_normal, bool p_tile, int p_previous_match);
-
-protected:
- // legacy support for non batched mode
- void _legacy_canvas_item_render_commands(RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material);
-
- // light scissoring
- bool _light_scissor_begin(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect) const;
- bool _light_find_intersection(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect, Rect2 &r_cliprect) const;
- void _calculate_scissor_threshold_area();
-
-private:
- // translating vertex formats prior to rendering
- void _translate_batches_to_vertex_colored_FVF();
- template <class BATCH_VERTEX_TYPE, bool INCLUDE_LIGHT_ANGLES, bool INCLUDE_MODULATE, bool INCLUDE_LARGE>
- void _translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type_flags);
-
-protected:
- // accessory funcs
- void _software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const;
- void _software_transform_vertex(Vector2 &r_v, const Transform2D &p_tr) const;
- TransformMode _find_transform_mode(const Transform2D &p_tr) const {
- // decided whether to do translate only for software transform
- if ((p_tr.elements[0].x == 1.0f) &&
- (p_tr.elements[0].y == 0.0f) &&
- (p_tr.elements[1].x == 0.0f) &&
- (p_tr.elements[1].y == 1.0f)) {
- return TM_TRANSLATE;
- }
-
- return TM_ALL;
- }
-
- typename T_STORAGE::Texture *_get_canvas_texture(const RID &p_texture) const {
- if (p_texture.is_valid()) {
- typename T_STORAGE::Texture *texture = get_storage()->texture_owner.get_or_null(p_texture);
-
- if (texture) {
- return texture->get_ptr();
- }
- }
-
- return 0;
- }
-
-public:
- Batch *_batch_request_new(bool p_blank = true) {
- Batch *batch = bdata.batches.request();
- if (!batch) {
- // grow the batches
- bdata.batches.grow();
-
- // and the temporary batches (used for color verts)
- bdata.batches_temp.reset();
- bdata.batches_temp.grow();
-
- // this should always succeed after growing
- batch = bdata.batches.request();
- RAST_DEBUG_ASSERT(batch);
- }
-
- if (p_blank)
- memset(batch, 0, sizeof(Batch));
-
- return batch;
- }
-
- BatchVertex *_batch_vertex_request_new() {
- return bdata.vertices.request();
- }
-
-protected:
- int godot4_commands_count(RendererCanvasRender::Item::Command *p_comm) const {
- int count = 0;
- while (p_comm) {
- count++;
- p_comm = p_comm->next;
- }
- return count;
- }
-
- unsigned int godot4_commands_to_vector(RendererCanvasRender::Item::Command *p_comm, LocalVector<RendererCanvasRender::Item::Command *> &p_list) {
- p_list.clear();
- while (p_comm) {
- p_list.push_back(p_comm);
- p_comm = p_comm->next;
- }
- return p_list.size();
- }
-};
-
-PREAMBLE(void)::batch_canvas_begin() {
- // diagnose_frame?
- bdata.frame_string = ""; // just in case, always set this as we don't want a string leak in release...
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
- if (bdata.settings_diagnose_frame) {
- bdata.diagnose_frame = false;
-
- uint32_t tick = OS::get_singleton()->get_ticks_msec();
- uint64_t frame = Engine::get_singleton()->get_frames_drawn();
-
- if (tick >= bdata.next_diagnose_tick) {
- bdata.next_diagnose_tick = tick + 10000;
-
- // the plus one is prevent starting diagnosis half way through frame
- bdata.diagnose_frame_number = frame + 1;
- }
-
- if (frame == bdata.diagnose_frame_number) {
- bdata.diagnose_frame = true;
- bdata.reset_stats();
- }
-
- if (bdata.diagnose_frame) {
- bdata.frame_string = "canvas_begin FRAME " + itos(frame) + "\n";
- }
- }
-#endif
-}
-
-PREAMBLE(void)::batch_canvas_end() {
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
- if (bdata.diagnose_frame) {
- bdata.frame_string += "canvas_end\n";
- if (bdata.stats_items_sorted) {
- bdata.frame_string += "\titems reordered: " + itos(bdata.stats_items_sorted) + "\n";
- }
- if (bdata.stats_light_items_joined) {
- bdata.frame_string += "\tlight items joined: " + itos(bdata.stats_light_items_joined) + "\n";
- }
-
- print_line(bdata.frame_string);
- }
-#endif
-}
-
-PREAMBLE(void)::batch_canvas_render_items_begin(const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform) {
- // if we are debugging, flash each frame between batching renderer and old version to compare for regressions
- if (bdata.settings_flash_batching) {
- if ((Engine::get_singleton()->get_frames_drawn() % 2) == 0)
- bdata.settings_use_batching = true;
- else
- bdata.settings_use_batching = false;
- }
-
- if (!bdata.settings_use_batching) {
- return;
- }
-
- // this only needs to be done when screen size changes, but this should be
- // infrequent enough
- _calculate_scissor_threshold_area();
-
- // set up render item state for all the z_indexes (this is common to all z_indexes)
- _render_item_state.reset();
- _render_item_state.item_group_modulate = p_modulate;
- _render_item_state.item_group_light = p_light;
- _render_item_state.item_group_base_transform = p_base_transform;
- _render_item_state.light_region.reset();
-
- // batch break must be preserved over the different z indices,
- // to prevent joining to an item on a previous index if not allowed
- _render_item_state.join_batch_break = false;
-
- // whether to join across z indices depends on whether there are z ranged lights.
- // joined z_index items can be wrongly classified with z ranged lights.
- bdata.join_across_z_indices = true;
-
- int light_count = 0;
- while (p_light) {
- light_count++;
-
- if ((p_light->z_min != RS::CANVAS_ITEM_Z_MIN) || (p_light->z_max != RS::CANVAS_ITEM_Z_MAX)) {
- // prevent joining across z indices. This would have caused visual regressions
- bdata.join_across_z_indices = false;
- }
-
- p_light = p_light->next_ptr;
- }
-
- // can't use the light region bitfield if there are too many lights
- // hopefully most games won't blow this limit..
- // if they do they will work but it won't batch join items just in case
- if (light_count > 64) {
- _render_item_state.light_region.too_many_lights = true;
- }
-}
-
-PREAMBLE(void)::batch_canvas_render_items_end() {
- if (!bdata.settings_use_batching) {
- return;
- }
-
- join_sorted_items();
-
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
- if (bdata.diagnose_frame) {
- bdata.frame_string += "items\n";
- }
-#endif
-
- // batching render is deferred until after going through all the z_indices, joining all the items
- get_this()->canvas_render_items_implementation(0, 0, _render_item_state.item_group_modulate,
- _render_item_state.item_group_light,
- _render_item_state.item_group_base_transform);
-
- bdata.items_joined.reset();
- bdata.item_refs.reset();
- bdata.sort_items.reset();
-}
-
-PREAMBLE(void)::batch_canvas_render_items(RendererCanvasRender::Item *p_item_list, int p_z, const Color &p_modulate, RendererCanvasRender::Light *p_light, const Transform2D &p_base_transform) {
- // stage 1 : join similar items, so that their state changes are not repeated,
- // and commands from joined items can be batched together
- if (bdata.settings_use_batching) {
- record_items(p_item_list, p_z);
- return;
- }
-
- // only legacy renders at this stage, batched renderer doesn't render until canvas_render_items_end()
- get_this()->canvas_render_items_implementation(p_item_list, p_z, p_modulate, p_light, p_base_transform);
-}
-
-// Default batches will not occur in software transform only items
-// EXCEPT IN THE CASE OF SINGLE RECTS (and this may well not occur, check the logic in prefill_join_item TYPE_RECT)
-// but can occur where transform commands have been sent during hardware batch
-PREAMBLE(void)::_prefill_default_batch(FillState &r_fill_state, int p_command_num, const RendererCanvasRender::Item &p_item) {
- if (r_fill_state.curr_batch->type == RasterizerStorageCommon::BT_DEFAULT) {
- // don't need to flush an extra transform command?
- if (!r_fill_state.transform_extra_command_number_p1) {
- // another default command, just add to the existing batch
- r_fill_state.curr_batch->num_commands++;
- } else {
-#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED)
- if (r_fill_state.transform_extra_command_number_p1 != p_command_num) {
- WARN_PRINT_ONCE("_prefill_default_batch : transform_extra_command_number_p1 != p_command_num");
- }
-#endif
- // if the first member of the batch is a transform we have to be careful
- if (!r_fill_state.curr_batch->num_commands) {
- // there can be leading useless extra transforms (sometimes happens with debug collision polys)
- // we need to rejig the first_command for the first useful transform
- r_fill_state.curr_batch->first_command += r_fill_state.transform_extra_command_number_p1 - 1;
- }
-
- // we do have a pending extra transform command to flush
- // either the extra transform is in the prior command, or not, in which case we need 2 batches
- r_fill_state.curr_batch->num_commands += 2;
-
- r_fill_state.transform_extra_command_number_p1 = 0; // mark as sent
- r_fill_state.extra_matrix_sent = true;
-
- // the original mode should always be hardware transform ..
- // test this assumption
- //CRASH_COND(r_fill_state.orig_transform_mode != TM_NONE);
- r_fill_state.transform_mode = r_fill_state.orig_transform_mode;
-
- // do we need to restore anything else?
- }
- } else {
- // end of previous different type batch, so start new default batch
-
- // first consider whether there is a dirty extra matrix to send
- if (r_fill_state.transform_extra_command_number_p1) {
- // get which command the extra is in, and blank all the records as it no longer is stored CPU side
- int extra_command = r_fill_state.transform_extra_command_number_p1 - 1; // plus 1 based
- r_fill_state.transform_extra_command_number_p1 = 0;
- r_fill_state.extra_matrix_sent = true;
-
- // send the extra to the GPU in a batch
- r_fill_state.curr_batch = _batch_request_new();
- r_fill_state.curr_batch->type = RasterizerStorageCommon::BT_DEFAULT;
- r_fill_state.curr_batch->first_command = extra_command;
- r_fill_state.curr_batch->num_commands = 1;
-
- // revert to the original transform mode
- // e.g. go back to NONE if we were in hardware transform mode
- r_fill_state.transform_mode = r_fill_state.orig_transform_mode;
-
- // reset the original transform if we are going back to software mode,
- // because the extra is now done on the GPU...
- // (any subsequent extras are sent directly to the GPU, no deferring)
- if (r_fill_state.orig_transform_mode != TM_NONE) {
- r_fill_state.transform_combined = p_item.final_transform;
- }
-
- // can possibly combine batch with the next one in some cases
- // this is more efficient than having an extra batch especially for the extra
- if ((extra_command + 1) == p_command_num) {
- r_fill_state.curr_batch->num_commands = 2;
- return;
- }
- }
-
- // start default batch
- r_fill_state.curr_batch = _batch_request_new();
- r_fill_state.curr_batch->type = RasterizerStorageCommon::BT_DEFAULT;
- r_fill_state.curr_batch->first_command = p_command_num;
- r_fill_state.curr_batch->num_commands = 1;
- }
-}
-
-PREAMBLE(int)::_batch_find_or_create_tex(const RID &p_texture, const RID &p_normal, bool p_tile, int p_previous_match) {
- // optimization .. in 99% cases the last matched value will be the same, so no need to traverse the list
- if (p_previous_match > 0) // if it is zero, it will get hit first in the linear search anyway
- {
- const BatchTex &batch_texture = bdata.batch_textures[p_previous_match];
-
- // note for future reference, if RID implementation changes, this could become more expensive
- if ((batch_texture.RID_texture == p_texture) && (batch_texture.RID_normal == p_normal)) {
- // tiling mode must also match
- bool tiles = batch_texture.tile_mode != BatchTex::TILE_OFF;
-
- if (tiles == p_tile)
- // match!
- return p_previous_match;
- }
- }
-
- // not the previous match .. we will do a linear search ... slower, but should happen
- // not very often except with non-batchable runs, which are going to be slow anyway
- // n.b. could possibly be replaced later by a fast hash table
- for (int n = 0; n < bdata.batch_textures.size(); n++) {
- const BatchTex &batch_texture = bdata.batch_textures[n];
- if ((batch_texture.RID_texture == p_texture) && (batch_texture.RID_normal == p_normal)) {
- // tiling mode must also match
- bool tiles = batch_texture.tile_mode != BatchTex::TILE_OFF;
-
- if (tiles == p_tile)
- // match!
- return n;
- }
- }
-
- // pushing back from local variable .. not ideal but has to use a Vector because non pod
- // due to RIDs
- BatchTex new_batch_tex;
- new_batch_tex.RID_texture = p_texture;
- new_batch_tex.RID_normal = p_normal;
-
- // get the texture
- typename T_STORAGE::Texture *texture = _get_canvas_texture(p_texture);
-
- if (texture) {
- // special case, there can be textures with no width or height
- int w = texture->width;
- int h = texture->height;
-
- if (!w || !h) {
- w = 1;
- h = 1;
- }
-
- new_batch_tex.tex_pixel_size.x = 1.0 / w;
- new_batch_tex.tex_pixel_size.y = 1.0 / h;
- new_batch_tex.flags = texture->flags;
- } else {
- // maybe doesn't need doing...
- new_batch_tex.tex_pixel_size.x = 1.0f;
- new_batch_tex.tex_pixel_size.y = 1.0f;
- new_batch_tex.flags = 0;
- }
-
- if (p_tile) {
- if (texture) {
- // default
- new_batch_tex.tile_mode = BatchTex::TILE_NORMAL;
-
- // no hardware support for non power of 2 tiling
- if (!get_storage()->config.support_npot_repeat_mipmap) {
- if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
- new_batch_tex.tile_mode = BatchTex::TILE_FORCE_REPEAT;
- }
- }
- } else {
- // this should not happen?
- new_batch_tex.tile_mode = BatchTex::TILE_OFF;
- }
- } else {
- new_batch_tex.tile_mode = BatchTex::TILE_OFF;
- }
-
- // push back
- bdata.batch_textures.push_back(new_batch_tex);
-
- return bdata.batch_textures.size() - 1;
-}
-
-PREAMBLE(void)::batch_constructor() {
- bdata.settings_use_batching = false;
-
-#ifdef GLES_OVER_GL
- use_nvidia_rect_workaround = GLOBAL_GET("rendering/quality/2d/use_nvidia_rect_flicker_workaround");
-#else
- // Not needed (a priori) on GLES devices
- use_nvidia_rect_workaround = false;
-#endif
-}
-
-PREAMBLE(void)::batch_initialize() {
-#define BATCHING_LOAD_PROJECT_SETTINGS
-
-#ifdef BATCHING_LOAD_PROJECT_SETTINGS
- bdata.settings_use_batching = GLOBAL_GET("rendering/batching/options/use_batching");
- bdata.settings_max_join_item_commands = GLOBAL_GET("rendering/batching/parameters/max_join_item_commands");
- bdata.settings_colored_vertex_format_threshold = GLOBAL_GET("rendering/batching/parameters/colored_vertex_format_threshold");
- bdata.settings_item_reordering_lookahead = GLOBAL_GET("rendering/batching/parameters/item_reordering_lookahead");
- bdata.settings_light_max_join_items = GLOBAL_GET("rendering/batching/lights/max_join_items");
- bdata.settings_use_single_rect_fallback = GLOBAL_GET("rendering/batching/options/single_rect_fallback");
- bdata.settings_use_software_skinning = GLOBAL_GET("rendering/quality/2d/use_software_skinning");
- bdata.settings_ninepatch_mode = GLOBAL_GET("rendering/quality/2d/ninepatch_mode");
-
- // alternatively only enable uv contract if pixel snap in use,
- // but with this enable bool, it should not be necessary
- bdata.settings_uv_contract = GLOBAL_GET("rendering/batching/precision/uv_contract");
- bdata.settings_uv_contract_amount = (float)GLOBAL_GET("rendering/batching/precision/uv_contract_amount") / 1000000.0f;
-
- // we can use the threshold to determine whether to turn scissoring off or on
- bdata.settings_scissor_threshold = GLOBAL_GET("rendering/batching/lights/scissor_area_threshold");
-#endif
-
- if (bdata.settings_scissor_threshold > 0.999f) {
- bdata.settings_scissor_lights = false;
- } else {
- bdata.settings_scissor_lights = true;
-
- // apply power of 4 relationship for the area, as most of the important changes
- // will be happening at low values of scissor threshold
- bdata.settings_scissor_threshold *= bdata.settings_scissor_threshold;
- bdata.settings_scissor_threshold *= bdata.settings_scissor_threshold;
- }
-
- // The sweet spot on my desktop for cache is actually smaller than the max, and this
- // is the default. This saves memory too so we will use it for now, needs testing to see whether this varies according
- // to device / platform.
-#ifdef BATCHING_LOAD_PROJECT_SETTINGS
- bdata.settings_batch_buffer_num_verts = GLOBAL_GET("rendering/batching/parameters/batch_buffer_size");
-
- // override the use_batching setting in the editor
- // (note that if the editor can't start, you can't change the use_batching project setting!)
- if (Engine::get_singleton()->is_editor_hint()) {
- bool use_in_editor = GLOBAL_GET("rendering/batching/options/use_batching_in_editor");
- bdata.settings_use_batching = use_in_editor;
-
- // fix some settings in the editor, as the performance not worth the risk
- bdata.settings_use_single_rect_fallback = false;
- }
-#endif
-
- // if we are using batching, we will purposefully disable the nvidia workaround.
- // This is because the only reason to use the single rect fallback is the approx 2x speed
- // of the uniform drawing technique. If we used nvidia workaround, speed would be
- // approx equal to the batcher drawing technique (indexed primitive + VB).
- if (bdata.settings_use_batching) {
- use_nvidia_rect_workaround = false;
- }
-
- // For debugging, if flash is set in project settings, it will flash on alternate frames
- // between the non-batched renderer and the batched renderer,
- // in order to find regressions.
- // This should not be used except during development.
- // make a note of the original choice in case we are flashing on and off the batching
- bdata.settings_use_batching_original_choice = bdata.settings_use_batching;
-
-#ifdef BATCHING_LOAD_PROJECT_SETTINGS
- bdata.settings_flash_batching = GLOBAL_GET("rendering/batching/debug/flash_batching");
-#endif
- if (!bdata.settings_use_batching) {
- // no flash when batching turned off
- bdata.settings_flash_batching = false;
- }
-
- // frame diagnosis. print out the batches every nth frame
- bdata.settings_diagnose_frame = false;
- if (!Engine::get_singleton()->is_editor_hint() && bdata.settings_use_batching) {
-#ifdef BATCHING_LOAD_PROJECT_SETTINGS
- bdata.settings_diagnose_frame = GLOBAL_GET("rendering/batching/debug/diagnose_frame");
-#endif
- }
-
- // the maximum num quads in a batch is limited by GLES2. We can have only 16 bit indices,
- // which means we can address a vertex buffer of max size 65535. 4 vertices are needed per quad.
-
- // Note this determines the memory use by the vertex buffer vector. max quads (65536/4)-1
- // but can be reduced to save memory if really required (will result in more batches though)
- const int max_possible_quads = (65536 / 4) - 1;
- const int min_possible_quads = 8; // some reasonable small value
-
- // value from project settings
- int max_quads = bdata.settings_batch_buffer_num_verts / 4;
-
- // sanity checks
- max_quads = CLAMP(max_quads, min_possible_quads, max_possible_quads);
- bdata.settings_max_join_item_commands = CLAMP(bdata.settings_max_join_item_commands, 0, 65535);
- bdata.settings_colored_vertex_format_threshold = CLAMP(bdata.settings_colored_vertex_format_threshold, 0.0f, 1.0f);
- bdata.settings_scissor_threshold = CLAMP(bdata.settings_scissor_threshold, 0.0f, 1.0f);
- bdata.settings_light_max_join_items = CLAMP(bdata.settings_light_max_join_items, 0, 65535);
- bdata.settings_item_reordering_lookahead = CLAMP(bdata.settings_item_reordering_lookahead, 0, 65535);
-
- // allow user to override the api usage techniques using project settings
- // bdata.buffer_mode_batch_upload_send_null = GLOBAL_GET("rendering/options/api_usage_batching/send_null");
- // bdata.buffer_mode_batch_upload_flag_stream = GLOBAL_GET("rendering/options/api_usage_batching/flag_stream");
-
- // for debug purposes, output a string with the batching options
- String batching_options_string = "OpenGL ES Batching: ";
- if (bdata.settings_use_batching) {
- batching_options_string += "ON";
-
- if (OS::get_singleton()->is_stdout_verbose()) {
- batching_options_string += "\n\tOPTIONS\n";
- batching_options_string += "\tmax_join_item_commands " + itos(bdata.settings_max_join_item_commands) + "\n";
- batching_options_string += "\tcolored_vertex_format_threshold " + String(Variant(bdata.settings_colored_vertex_format_threshold)) + "\n";
- batching_options_string += "\tbatch_buffer_size " + itos(bdata.settings_batch_buffer_num_verts) + "\n";
- batching_options_string += "\tlight_scissor_area_threshold " + String(Variant(bdata.settings_scissor_threshold)) + "\n";
-
- batching_options_string += "\titem_reordering_lookahead " + itos(bdata.settings_item_reordering_lookahead) + "\n";
- batching_options_string += "\tlight_max_join_items " + itos(bdata.settings_light_max_join_items) + "\n";
- batching_options_string += "\tsingle_rect_fallback " + String(Variant(bdata.settings_use_single_rect_fallback)) + "\n";
-
- batching_options_string += "\tdebug_flash " + String(Variant(bdata.settings_flash_batching)) + "\n";
- batching_options_string += "\tdiagnose_frame " + String(Variant(bdata.settings_diagnose_frame));
- }
-
- print_line(batching_options_string);
- }
-
- // special case, for colored vertex format threshold.
- // as the comparison is >=, we want to be able to totally turn on or off
- // conversion to colored vertex format at the extremes, so we will force
- // 1.0 to be just above 1.0
- if (bdata.settings_colored_vertex_format_threshold > 0.995f) {
- bdata.settings_colored_vertex_format_threshold = 1.01f;
- }
-
- // save memory when batching off
- if (!bdata.settings_use_batching) {
- max_quads = 0;
- }
-
- uint32_t sizeof_batch_vert = sizeof(BatchVertex);
-
- bdata.max_quads = max_quads;
-
- // 4 verts per quad
- bdata.vertex_buffer_size_units = max_quads * 4;
-
- // the index buffer can be longer than 65535, only the indices need to be within this range
- bdata.index_buffer_size_units = max_quads * 6;
-
- const int max_verts = bdata.vertex_buffer_size_units;
-
- // this comes out at approx 64K for non-colored vertex buffer, and 128K for colored vertex buffer
- bdata.vertex_buffer_size_bytes = max_verts * sizeof_batch_vert;
- bdata.index_buffer_size_bytes = bdata.index_buffer_size_units * 2; // 16 bit inds
-
- // create equal number of normal and (max) unit sized verts (as the normal may need to be translated to a larger FVF)
- bdata.vertices.create(max_verts); // 512k
- bdata.unit_vertices.create(max_verts, sizeof(BatchVertexLarge));
-
- // extra data per vert needed for larger FVFs
- bdata.light_angles.create(max_verts);
- bdata.vertex_colors.create(max_verts);
- bdata.vertex_modulates.create(max_verts);
- bdata.vertex_transforms.create(max_verts);
-
- // num batches will be auto increased dynamically if required
- bdata.batches.create(1024);
- bdata.batches_temp.create(bdata.batches.max_size());
-
- // batch textures can also be increased dynamically
- bdata.batch_textures.create(32);
-}
-
-PREAMBLE(bool)::_light_scissor_begin(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect) const {
- float area_item = p_item_rect.size.x * p_item_rect.size.y; // double check these are always positive
-
- // quick reject .. the area of pixels saved can never be more than the area of the item
- if (area_item < bdata.scissor_threshold_area) {
- return false;
- }
-
- Rect2 cliprect;
- if (!_light_find_intersection(p_item_rect, p_light_xform, p_light_rect, cliprect)) {
- // should not really occur .. but just in case
- cliprect = Rect2(0, 0, 0, 0);
- } else {
- // some conditions not to scissor
- // determine the area (fill rate) that will be saved
- float area_cliprect = cliprect.size.x * cliprect.size.y;
- float area_saved = area_item - area_cliprect;
-
- // if area saved is too small, don't scissor
- if (area_saved < bdata.scissor_threshold_area) {
- return false;
- }
- }
-
- int rh = get_storage()->frame.current_rt->height;
-
- int y = rh - (cliprect.position.y + cliprect.size.y);
- get_this()->gl_enable_scissor(cliprect.position.x, y, cliprect.size.width, cliprect.size.height);
-
- return true;
-}
-
-PREAMBLE(bool)::_light_find_intersection(const Rect2 &p_item_rect, const Transform2D &p_light_xform, const Rect2 &p_light_rect, Rect2 &r_cliprect) const {
- // transform light to world space (note this is done in the earlier intersection test, so could
- // be made more efficient)
- Vector2 pts[4] = {
- p_light_xform.xform(p_light_rect.position),
- p_light_xform.xform(Vector2(p_light_rect.position.x + p_light_rect.size.x, p_light_rect.position.y)),
- p_light_xform.xform(Vector2(p_light_rect.position.x, p_light_rect.position.y + p_light_rect.size.y)),
- p_light_xform.xform(Vector2(p_light_rect.position.x + p_light_rect.size.x, p_light_rect.position.y + p_light_rect.size.y)),
- };
-
- // calculate the light bound rect in world space
- Rect2 lrect(pts[0].x, pts[0].y, 0, 0);
- for (int n = 1; n < 4; n++) {
- lrect.expand_to(pts[n]);
- }
-
- // intersection between the 2 rects
- // they should probably always intersect, because of earlier check, but just in case...
- if (!p_item_rect.intersects(lrect))
- return false;
-
- // note this does almost the same as Rect2.clip but slightly more efficient for our use case
- r_cliprect.position.x = MAX(p_item_rect.position.x, lrect.position.x);
- r_cliprect.position.y = MAX(p_item_rect.position.y, lrect.position.y);
-
- Point2 item_rect_end = p_item_rect.position + p_item_rect.size;
- Point2 lrect_end = lrect.position + lrect.size;
-
- r_cliprect.size.x = MIN(item_rect_end.x, lrect_end.x) - r_cliprect.position.x;
- r_cliprect.size.y = MIN(item_rect_end.y, lrect_end.y) - r_cliprect.position.y;
-
- return true;
-}
-
-PREAMBLE(void)::_calculate_scissor_threshold_area() {
- if (!bdata.settings_scissor_lights) {
- return;
- }
-
- // scissor area threshold is 0.0 to 1.0 in the settings for ease of use.
- // we need to translate to an absolute area to determine quickly whether
- // to scissor.
- if (bdata.settings_scissor_threshold < 0.0001f) {
- bdata.scissor_threshold_area = -1.0f; // will always pass
- } else {
- // in pixels
- int w = get_storage()->frame.current_rt->width;
- int h = get_storage()->frame.current_rt->height;
-
- int screen_area = w * h;
-
- bdata.scissor_threshold_area = bdata.settings_scissor_threshold * screen_area;
- }
-}
-
-PREAMBLE(void)::render_joined_item_commands(const BItemJoined &p_bij, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material, bool p_lit) {
- RendererCanvasRender::Item *item = 0;
- RendererCanvasRender::Item *first_item = bdata.item_refs[p_bij.first_item_ref].item;
-
- // fill_state and bdata have once off setup per joined item, and a smaller reset on flush
- FillState fill_state;
- fill_state.reset_joined_item(p_bij.use_hardware_transform());
-
- bdata.reset_joined_item();
-
- // should this joined item be using large FVF?
- if (p_bij.flags & RasterizerStorageCommon::USE_MODULATE_FVF) {
- bdata.use_modulate = true;
- bdata.fvf = RasterizerStorageCommon::FVF_MODULATED;
- }
- if (p_bij.flags & RasterizerStorageCommon::USE_LARGE_FVF) {
- bdata.use_modulate = true;
- bdata.use_large_verts = true;
- bdata.fvf = RasterizerStorageCommon::FVF_LARGE;
- }
-
- // in the special case of custom shaders that read from VERTEX (i.e. vertex position)
- // we want to disable software transform of extra matrix
- if (bdata.joined_item_batch_flags & RasterizerStorageCommon::PREVENT_VERTEX_BAKING) {
- fill_state.extra_matrix_sent = true;
- }
-
- for (unsigned int i = 0; i < p_bij.num_item_refs; i++) {
- const BItemRef &ref = bdata.item_refs[p_bij.first_item_ref + i];
- item = ref.item;
-
- if (!p_lit) {
- // if not lit we use the complex calculated final modulate
- fill_state.final_modulate = ref.final_modulate;
- } else {
- // if lit we ignore canvas modulate and just use the item modulate
- fill_state.final_modulate = item->final_modulate;
- }
-
- // ONCE OFF fill state setup, that will be retained over multiple calls to
- // prefill_joined_item()
- fill_state.transform_combined = item->final_transform;
-
- // decide the initial transform mode, and make a backup
- // in orig_transform_mode in case we need to switch back
- if (!fill_state.use_hardware_transform) {
- fill_state.transform_mode = _find_transform_mode(fill_state.transform_combined);
- } else {
- fill_state.transform_mode = TM_NONE;
- }
- fill_state.orig_transform_mode = fill_state.transform_mode;
-
- // keep track of when we added an extra matrix
- // so we can defer sending until we see a default command
- fill_state.transform_extra_command_number_p1 = 0;
-
- RendererCanvasRender::Item::Command *current_command = item->commands;
- while (current_command) {
- // fill as many batches as possible (until all done, or the vertex buffer is full)
- bool bFull = get_this()->prefill_joined_item(fill_state, current_command, item, p_current_clip, r_reclip, p_material);
-
- if (bFull) {
- // always pass first item (commands for default are always first item)
- flush_render_batches(first_item, p_current_clip, r_reclip, p_material, fill_state.sequence_batch_type_flags);
-
- // zero all the batch data ready for a new run
- bdata.reset_flush();
-
- // don't zero all the fill state, some may need to be preserved
- fill_state.reset_flush();
- }
- }
- }
-
- // flush if any left
- flush_render_batches(first_item, p_current_clip, r_reclip, p_material, fill_state.sequence_batch_type_flags);
-
- // zero all the batch data ready for a new run
- bdata.reset_flush();
-}
-
-PREAMBLE(void)::_legacy_canvas_item_render_commands(RendererCanvasRender::Item *p_item, RendererCanvasRender::Item *p_current_clip, bool &r_reclip, typename T_STORAGE::Material *p_material) {
- // reuse the same list each time to prevent needless dynamic allocations
- unsigned int command_count = godot4_commands_to_vector(p_item->commands, bdata.command_shortlist);
- RendererCanvasRender::Item::Command *const *commands = nullptr;
- if (command_count) {
- commands = &bdata.command_shortlist[0];
- }
-
- // legacy .. just create one massive batch and render everything as before
- bdata.batches.reset();
- Batch *batch = _batch_request_new();
- batch->type = RasterizerStorageCommon::BT_DEFAULT;
- batch->num_commands = command_count;
-
- get_this()->render_batches(commands, p_current_clip, r_reclip, p_material);
- bdata.reset_flush();
-}
-
-PREAMBLE(void)::record_items(RendererCanvasRender::Item *p_item_list, int p_z) {
- while (p_item_list) {
- BSortItem *s = bdata.sort_items.request_with_grow();
-
- s->item = p_item_list;
- s->z_index = p_z;
-
- p_item_list = p_item_list->next;
- }
-}
-
-PREAMBLE(void)::join_sorted_items() {
-}
-
-PREAMBLE(void)::_software_transform_vertex(BatchVector2 &r_v, const Transform2D &p_tr) const {
- Vector2 vc(r_v.x, r_v.y);
- vc = p_tr.xform(vc);
- r_v.set(vc);
-}
-
-PREAMBLE(void)::_software_transform_vertex(Vector2 &r_v, const Transform2D &p_tr) const {
- r_v = p_tr.xform(r_v);
-}
-
-PREAMBLE(void)::_translate_batches_to_vertex_colored_FVF() {
- // zeros the size and sets up how big each unit is
- bdata.unit_vertices.prepare(sizeof(BatchVertexColored));
-
- const BatchColor *source_vertex_colors = &bdata.vertex_colors[0];
- RAST_DEBUG_ASSERT(bdata.vertex_colors.size() == bdata.vertices.size());
-
- int num_verts = bdata.vertices.size();
-
- for (int n = 0; n < num_verts; n++) {
- const BatchVertex &bv = bdata.vertices[n];
-
- BatchVertexColored *cv = (BatchVertexColored *)bdata.unit_vertices.request();
-
- cv->pos = bv.pos;
- cv->uv = bv.uv;
- cv->col = *source_vertex_colors++;
- }
-}
-
-// Translation always involved adding color to the FVF, which enables
-// joining of batches that have different colors.
-// There is a trade off. Non colored verts are smaller so work faster, but
-// there comes a point where it is better to just use colored verts to avoid lots of
-// batches.
-// In addition this can optionally add light angles to the FVF, necessary for normal mapping.
-T_PREAMBLE
-template <class BATCH_VERTEX_TYPE, bool INCLUDE_LIGHT_ANGLES, bool INCLUDE_MODULATE, bool INCLUDE_LARGE>
-void C_PREAMBLE::_translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type_flags) {
- bool include_poly_color = false;
-
- // we ONLY want to include the color verts in translation when using polys,
- // as rects do not write vertex colors, only colors per batch.
- if (p_sequence_batch_type_flags & RasterizerStorageCommon::BTF_POLY) {
- include_poly_color = INCLUDE_LIGHT_ANGLES | INCLUDE_MODULATE | INCLUDE_LARGE;
- }
-
- // zeros the size and sets up how big each unit is
- bdata.unit_vertices.prepare(sizeof(BATCH_VERTEX_TYPE));
- bdata.batches_temp.reset();
-
- // As the vertices_colored and batches_temp are 'mirrors' of the non-colored version,
- // the sizes should be equal, and allocations should never fail. Hence the use of debug
- // asserts to check program flow, these should not occur at runtime unless the allocation
- // code has been altered.
- RAST_DEBUG_ASSERT(bdata.unit_vertices.max_size() == bdata.vertices.max_size());
- RAST_DEBUG_ASSERT(bdata.batches_temp.max_size() == bdata.batches.max_size());
-
- Color curr_col(-1.0f, -1.0f, -1.0f, -1.0f);
-
- Batch *dest_batch = nullptr;
-
- const BatchColor *source_vertex_colors = &bdata.vertex_colors[0];
- const float *source_light_angles = &bdata.light_angles[0];
- const BatchColor *source_vertex_modulates = &bdata.vertex_modulates[0];
- const BatchTransform *source_vertex_transforms = &bdata.vertex_transforms[0];
-
- // translate the batches into vertex colored batches
- for (int n = 0; n < bdata.batches.size(); n++) {
- const Batch &source_batch = bdata.batches[n];
-
- // does source batch use light angles?
- const BatchTex &btex = bdata.batch_textures[source_batch.batch_texture_id];
- bool source_batch_uses_light_angles = btex.RID_normal != RID();
-
- bool needs_new_batch = true;
-
- if (dest_batch) {
- if (dest_batch->type == source_batch.type) {
- if (source_batch.type == RasterizerStorageCommon::BT_RECT) {
- if (dest_batch->batch_texture_id == source_batch.batch_texture_id) {
- // add to previous batch
- dest_batch->num_commands += source_batch.num_commands;
- needs_new_batch = false;
-
- // create the colored verts (only if not default)
- //int first_vert = source_batch.first_quad * 4;
- //int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands);
- int first_vert = source_batch.first_vert;
- int end_vert = first_vert + (4 * source_batch.num_commands);
-
- for (int v = first_vert; v < end_vert; v++) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertices.size());
- const BatchVertex &bv = bdata.vertices[v];
- BATCH_VERTEX_TYPE *cv = (BATCH_VERTEX_TYPE *)bdata.unit_vertices.request();
- RAST_DEBUG_ASSERT(cv);
- cv->pos = bv.pos;
- cv->uv = bv.uv;
- cv->col = source_batch.color;
-
- if (INCLUDE_LIGHT_ANGLES) {
- RAST_DEV_DEBUG_ASSERT(bdata.light_angles.size());
- // this is required to allow compilation with non light angle vertex.
- // it should be compiled out.
- BatchVertexLightAngled *lv = (BatchVertexLightAngled *)cv;
- if (source_batch_uses_light_angles)
- lv->light_angle = *source_light_angles++;
- else
- lv->light_angle = 0.0f; // dummy, unused in vertex shader (could possibly be left uninitialized, but probably bad idea)
- } // if including light angles
-
- if (INCLUDE_MODULATE) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertex_modulates.size());
- BatchVertexModulated *mv = (BatchVertexModulated *)cv;
- mv->modulate = *source_vertex_modulates++;
- } // including modulate
-
- if (INCLUDE_LARGE) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertex_transforms.size());
- BatchVertexLarge *lv = (BatchVertexLarge *)cv;
- lv->transform = *source_vertex_transforms++;
- } // if including large
- }
- } // textures match
- } else {
- // default
- // we can still join, but only under special circumstances
- // does this ever happen? not sure at this stage, but left for future expansion
- uint32_t source_last_command = source_batch.first_command + source_batch.num_commands;
- if (source_last_command == dest_batch->first_command) {
- dest_batch->num_commands += source_batch.num_commands;
- needs_new_batch = false;
- } // if the commands line up exactly
- }
- } // if both batches are the same type
-
- } // if dest batch is valid
-
- if (needs_new_batch) {
- dest_batch = bdata.batches_temp.request();
- RAST_DEBUG_ASSERT(dest_batch);
-
- *dest_batch = source_batch;
-
- // create the colored verts (only if not default)
- if (source_batch.type != RasterizerStorageCommon::BT_DEFAULT) {
- // int first_vert = source_batch.first_quad * 4;
- // int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands);
- int first_vert = source_batch.first_vert;
- int end_vert = first_vert + (4 * source_batch.num_commands);
-
- for (int v = first_vert; v < end_vert; v++) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertices.size());
- const BatchVertex &bv = bdata.vertices[v];
- BATCH_VERTEX_TYPE *cv = (BATCH_VERTEX_TYPE *)bdata.unit_vertices.request();
- RAST_DEBUG_ASSERT(cv);
- cv->pos = bv.pos;
- cv->uv = bv.uv;
-
- // polys are special, they can have per vertex colors
- if (!include_poly_color) {
- cv->col = source_batch.color;
- } else {
- RAST_DEV_DEBUG_ASSERT(bdata.vertex_colors.size());
- cv->col = *source_vertex_colors++;
- }
-
- if (INCLUDE_LIGHT_ANGLES) {
- RAST_DEV_DEBUG_ASSERT(bdata.light_angles.size());
- // this is required to allow compilation with non light angle vertex.
- // it should be compiled out.
- BatchVertexLightAngled *lv = (BatchVertexLightAngled *)cv;
- if (source_batch_uses_light_angles)
- lv->light_angle = *source_light_angles++;
- else
- lv->light_angle = 0.0f; // dummy, unused in vertex shader (could possibly be left uninitialized, but probably bad idea)
- } // if using light angles
-
- if (INCLUDE_MODULATE) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertex_modulates.size());
- BatchVertexModulated *mv = (BatchVertexModulated *)cv;
- mv->modulate = *source_vertex_modulates++;
- } // including modulate
-
- if (INCLUDE_LARGE) {
- RAST_DEV_DEBUG_ASSERT(bdata.vertex_transforms.size());
- BatchVertexLarge *lv = (BatchVertexLarge *)cv;
- lv->transform = *source_vertex_transforms++;
- } // if including large
- }
- }
- }
- }
-
- // copy the temporary batches to the master batch list (this could be avoided but it makes the code cleaner)
- bdata.batches.copy_from(bdata.batches_temp);
-}
-
-PREAMBLE(bool)::_disallow_item_join_if_batch_types_too_different(RenderItemState &r_ris, uint32_t btf_allowed) {
- r_ris.joined_item_batch_type_flags_curr |= btf_allowed;
-
- bool disallow = false;
-
- if (r_ris.joined_item_batch_type_flags_prev & (~btf_allowed))
- disallow = true;
-
- return disallow;
-}
-
-#undef PREAMBLE
-#undef T_PREAMBLE
-#undef C_PREAMBLE
-
-#endif // RASTERIZER_CANVAS_BATCHER_H
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 686910e1c6..270725ee63 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -29,17 +29,20 @@
/*************************************************************************/
#include "rasterizer_canvas_gles3.h"
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+
+#ifdef GLES3_ENABLED
#include "core/os/os.h"
-#include "drivers/gles3/rasterizer_asserts.h"
#include "rasterizer_scene_gles3.h"
#include "rasterizer_storage_gles3.h"
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_server_default.h"
+#ifndef GLES_OVER_GL
+#define glClearDepth glClearDepthf
+#endif
+
//static const GLenum gl_primitive[] = {
// GL_POINTS,
// GL_LINES,
@@ -50,1660 +53,1417 @@
// GL_TRIANGLE_FAN
//};
-#if 0
-void RasterizerCanvasGLES3::_batch_upload_buffers() {
- // noop?
- if (!bdata.vertices.size())
- return;
+void RasterizerCanvasGLES3::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
+ p_mat4[0] = p_transform.elements[0][0];
+ p_mat4[1] = p_transform.elements[0][1];
+ p_mat4[2] = 0;
+ p_mat4[3] = 0;
+ p_mat4[4] = p_transform.elements[1][0];
+ p_mat4[5] = p_transform.elements[1][1];
+ p_mat4[6] = 0;
+ p_mat4[7] = 0;
+ p_mat4[8] = 0;
+ p_mat4[9] = 0;
+ p_mat4[10] = 1;
+ p_mat4[11] = 0;
+ p_mat4[12] = p_transform.elements[2][0];
+ p_mat4[13] = p_transform.elements[2][1];
+ p_mat4[14] = 0;
+ p_mat4[15] = 1;
+}
- glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer);
+void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) {
+ p_mat2x4[0] = p_transform.elements[0][0];
+ p_mat2x4[1] = p_transform.elements[1][0];
+ p_mat2x4[2] = 0;
+ p_mat2x4[3] = p_transform.elements[2][0];
- // usage flag is a project setting
- GLenum buffer_usage_flag = GL_DYNAMIC_DRAW;
- if (bdata.buffer_mode_batch_upload_flag_stream) {
- buffer_usage_flag = GL_STREAM_DRAW;
- }
-
- // orphan the old (for now)
- if (bdata.buffer_mode_batch_upload_send_null) {
- glBufferData(GL_ARRAY_BUFFER, 0, 0, buffer_usage_flag); // GL_DYNAMIC_DRAW);
- }
+ p_mat2x4[4] = p_transform.elements[0][1];
+ p_mat2x4[5] = p_transform.elements[1][1];
+ p_mat2x4[6] = 0;
+ p_mat2x4[7] = p_transform.elements[2][1];
+}
- switch (bdata.fvf) {
- case RasterizerStorageCommon::FVF_UNBATCHED: // should not happen
- break;
- case RasterizerStorageCommon::FVF_REGULAR: // no change
- glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertex) * bdata.vertices.size(), bdata.vertices.get_data(), buffer_usage_flag);
- break;
- case RasterizerStorageCommon::FVF_COLOR:
- glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexColored) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag);
- break;
- case RasterizerStorageCommon::FVF_LIGHT_ANGLE:
- glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexLightAngled) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag);
- break;
- case RasterizerStorageCommon::FVF_MODULATED:
- glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexModulated) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag);
- break;
- case RasterizerStorageCommon::FVF_LARGE:
- glBufferData(GL_ARRAY_BUFFER, sizeof(BatchVertexLarge) * bdata.unit_vertices.size(), bdata.unit_vertices.get_unit(0), buffer_usage_flag);
- break;
- }
+void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
+ p_mat2x3[0] = p_transform.elements[0][0];
+ p_mat2x3[1] = p_transform.elements[0][1];
+ p_mat2x3[2] = p_transform.elements[1][0];
+ p_mat2x3[3] = p_transform.elements[1][1];
+ p_mat2x3[4] = p_transform.elements[2][0];
+ p_mat2x3[5] = p_transform.elements[2][1];
+}
- // might not be necessary
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4) {
+ p_mat4[0] = p_transform.basis.elements[0][0];
+ p_mat4[1] = p_transform.basis.elements[1][0];
+ p_mat4[2] = p_transform.basis.elements[2][0];
+ p_mat4[3] = 0;
+ p_mat4[4] = p_transform.basis.elements[0][1];
+ p_mat4[5] = p_transform.basis.elements[1][1];
+ p_mat4[6] = p_transform.basis.elements[2][1];
+ p_mat4[7] = 0;
+ p_mat4[8] = p_transform.basis.elements[0][2];
+ p_mat4[9] = p_transform.basis.elements[1][2];
+ p_mat4[10] = p_transform.basis.elements[2][2];
+ p_mat4[11] = 0;
+ p_mat4[12] = p_transform.origin.x;
+ p_mat4[13] = p_transform.origin.y;
+ p_mat4[14] = p_transform.origin.z;
+ p_mat4[15] = 1;
}
-void RasterizerCanvasGLES3::_batch_render_lines(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material, bool p_anti_alias) {
- _set_texture_rect_mode(false);
+void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
+ storage->frame.current_rt = nullptr;
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
+ storage->_set_current_render_target(p_to_render_target);
- _bind_canvas_texture(RID(), RID());
+ Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse();
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, (float *)&p_batch.color);
+ // TODO: Setup Directional Lights
-#ifdef GLES_OVER_GL
- if (p_anti_alias)
- glEnable(GL_LINE_SMOOTH);
-#endif
+ // TODO: Setup lights
- int sizeof_vert = sizeof(BatchVertex);
+ {
+ //update canvas state uniform buffer
+ StateBuffer state_buffer;
- // bind the index and vertex buffer
- glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer);
+ Size2i ssize = storage->render_target_get_size(p_to_render_target);
- uint64_t pointer = 0;
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof_vert, (const void *)pointer);
+ Transform3D screen_transform;
+ screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
+ screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f));
+ _update_transform_to_mat4(screen_transform, state_buffer.screen_transform);
+ _update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform);
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
+ Transform2D normal_transform = p_canvas_transform;
+ normal_transform.elements[0].normalize();
+ normal_transform.elements[1].normalize();
+ normal_transform.elements[2] = Vector2();
+ _update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform);
- int64_t offset = p_batch.first_vert; // 6 inds per quad at 2 bytes each
+ state_buffer.canvas_modulate[0] = p_modulate.r;
+ state_buffer.canvas_modulate[1] = p_modulate.g;
+ state_buffer.canvas_modulate[2] = p_modulate.b;
+ state_buffer.canvas_modulate[3] = p_modulate.a;
- int num_elements = p_batch.num_commands * 2;
- glDrawArrays(GL_LINES, offset, num_elements);
+ Size2 render_target_size = storage->render_target_get_size(p_to_render_target);
+ state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x;
+ state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
- storage->info.render._2d_draw_call_count++;
+ state_buffer.time = storage->frame.time;
+ state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel;
- // may not be necessary .. state change optimization still TODO
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ state_buffer.directional_light_count = 0; //directional_light_count;
-#ifdef GLES_OVER_GL
- if (p_anti_alias)
- glDisable(GL_LINE_SMOOTH);
-#endif
-}
+ Vector2 canvas_scale = p_canvas_transform.get_scale();
-void RasterizerCanvasGLES3::_batch_render_generic(const Batch &p_batch, RasterizerStorageGLES3::Material *p_material) {
- ERR_FAIL_COND(p_batch.num_commands <= 0);
-
- const bool &use_light_angles = bdata.use_light_angles;
- const bool &use_modulate = bdata.use_modulate;
- const bool &use_large_verts = bdata.use_large_verts;
- const bool &colored_verts = bdata.use_colored_vertices | use_light_angles | use_modulate | use_large_verts;
-
- int sizeof_vert;
-
- switch (bdata.fvf) {
- default:
- sizeof_vert = 0; // prevent compiler warning - this should never happen
- break;
- case RasterizerStorageCommon::FVF_UNBATCHED: {
- sizeof_vert = 0; // prevent compiler warning - this should never happen
- return;
- } break;
- case RasterizerStorageCommon::FVF_REGULAR: // no change
- sizeof_vert = sizeof(BatchVertex);
- break;
- case RasterizerStorageCommon::FVF_COLOR:
- sizeof_vert = sizeof(BatchVertexColored);
- break;
- case RasterizerStorageCommon::FVF_LIGHT_ANGLE:
- sizeof_vert = sizeof(BatchVertexLightAngled);
- break;
- case RasterizerStorageCommon::FVF_MODULATED:
- sizeof_vert = sizeof(BatchVertexModulated);
- break;
- case RasterizerStorageCommon::FVF_LARGE:
- sizeof_vert = sizeof(BatchVertexLarge);
- break;
- }
+ state_buffer.sdf_to_screen[0] = render_target_size.width / canvas_scale.x;
+ state_buffer.sdf_to_screen[1] = render_target_size.height / canvas_scale.y;
- // make sure to set all conditionals BEFORE binding the shader
- _set_texture_rect_mode(false, use_light_angles, use_modulate, use_large_verts);
+ state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0];
+ state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1];
- // batch tex
- const BatchTex &tex = bdata.batch_textures[p_batch.batch_texture_id];
- //VSG::rasterizer->gl_check_for_error();
+ Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target);
+ Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale);
- // force repeat is set if non power of 2 texture, and repeat is needed if hardware doesn't support npot
- if (tex.tile_mode == BatchTex::TILE_FORCE_REPEAT) {
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, true);
- }
+ state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width;
+ state_buffer.sdf_to_tex[1] = 1.0 / sdf_tex_rect.size.height;
+ state_buffer.sdf_to_tex[2] = -sdf_tex_rect.position.x / sdf_tex_rect.size.width;
+ state_buffer.sdf_to_tex[3] = -sdf_tex_rect.position.y / sdf_tex_rect.size.height;
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
+ //print_line("w: " + itos(ssize.width) + " s: " + rtos(canvas_scale));
+ state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.canvas_state_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
- _bind_canvas_texture(tex.RID_texture, tex.RID_normal);
-
- // bind the index and vertex buffer
- glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer);
+ {
+ state.default_filter = p_default_filter;
+ state.default_repeat = p_default_repeat;
+ }
- uint64_t pointer = 0;
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof_vert, (const void *)pointer);
+ state.current_tex = RID();
+ state.current_tex_ptr = NULL;
+ state.current_normal = RID();
+ state.current_specular = RID();
+ state.canvas_texscreen_used = false;
- // always send UVs, even within a texture specified because a shader can still use UVs
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (2 * 4)));
+ r_sdf_used = false;
+ int item_count = 0;
- // color
- if (!colored_verts) {
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, p_batch.color.get_data());
- } else {
- glEnableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (4 * 4)));
- }
-
- if (use_light_angles) {
- glEnableVertexAttribArray(RS::ARRAY_TANGENT);
- glVertexAttribPointer(RS::ARRAY_TANGENT, 1, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (8 * 4)));
- }
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+ Item *ci = p_item_list;
+ while (ci) {
+ // just add all items for now
+ items[item_count++] = ci;
+
+ if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) {
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
+ //then reset
+ item_count = 0;
+ }
- if (use_modulate) {
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV2);
- glVertexAttribPointer(RS::ARRAY_TEX_UV2, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (9 * 4)));
+ ci = ci->next;
}
+}
- if (use_large_verts) {
- glEnableVertexAttribArray(RS::ARRAY_BONES);
- glVertexAttribPointer(RS::ARRAY_BONES, 2, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (13 * 4)));
- glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);
- glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof_vert, CAST_INT_TO_UCHAR_PTR(pointer + (15 * 4)));
- }
+void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
+ Item *current_clip = nullptr;
- // We only want to set the GL wrapping mode if the texture is not already tiled (i.e. set in Import).
- // This is an optimization left over from the legacy renderer.
- // If we DID set tiling in the API, and reverted to clamped, then the next draw using this texture
- // may use clamped mode incorrectly.
- bool tex_is_already_tiled = tex.flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT;
-
- if (tex.tile_mode == BatchTex::TILE_NORMAL) {
- // if the texture is imported as tiled, no need to set GL state, as it will already be bound with repeat
- if (!tex_is_already_tiled) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
- }
+ Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
- // we need to convert explicitly from pod Vec2 to Vector2 ...
- // could use a cast but this might be unsafe in future
- Vector2 tps;
- tex.tex_pixel_size.to(tps);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, tps);
-
- switch (p_batch.type) {
- default: {
- // prevent compiler warning
- } break;
- case RasterizerStorageCommon::BT_RECT: {
- int64_t offset = p_batch.first_vert * 3;
-
- int num_elements = p_batch.num_commands * 6;
- glDrawElements(GL_TRIANGLES, num_elements, GL_UNSIGNED_SHORT, (void *)offset);
- } break;
- case RasterizerStorageCommon::BT_POLY: {
- int64_t offset = p_batch.first_vert;
-
- int num_elements = p_batch.num_commands;
- glDrawArrays(GL_TRIANGLES, offset, num_elements);
- } break;
- }
+ RID framebuffer;
+ Vector<Color> clear_colors;
- storage->info.render._2d_draw_call_count++;
-
- switch (tex.tile_mode) {
- case BatchTex::TILE_FORCE_REPEAT: {
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, false);
- } break;
- case BatchTex::TILE_NORMAL: {
- // if the texture is imported as tiled, no need to revert GL state
- if (!tex_is_already_tiled) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
- } break;
- default: {
- } break;
- }
+ canvas_begin();
- // could these have ifs?
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glDisableVertexAttribArray(RS::ARRAY_TANGENT);
- glDisableVertexAttribArray(RS::ARRAY_TEX_UV2);
- glDisableVertexAttribArray(RS::ARRAY_BONES);
- glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);
+ RID prev_material;
+ uint32_t index = 0;
- // may not be necessary .. state change optimization still TODO
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-}
-#endif
-void RasterizerCanvasGLES3::render_batches(Item::Command *const *p_commands, Item *p_current_clip, bool &r_reclip, RasterizerStorageGLES3::Material *p_material) {
- int num_batches = bdata.batches.size();
+ for (int i = 0; i < p_item_count; i++) {
+ Item *ci = items[i];
- for (int batch_num = 0; batch_num < num_batches; batch_num++) {
- const Batch &batch = bdata.batches[batch_num];
+ RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
+ RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material);
- switch (batch.type) {
- case RasterizerStorageCommon::BT_RECT: {
- //_batch_render_generic(batch, p_material);
- } break;
- case RasterizerStorageCommon::BT_POLY: {
- //_batch_render_generic(batch, p_material);
- } break;
- case RasterizerStorageCommon::BT_LINE: {
- //_batch_render_lines(batch, p_material, false);
- } break;
- case RasterizerStorageCommon::BT_LINE_AA: {
- //_batch_render_lines(batch, p_material, true);
- } break;
- default: {
- int end_command = batch.first_command + batch.num_commands;
+ if (material.is_null() && ci->canvas_group != nullptr) {
+ material = default_canvas_group_material;
+ }
- for (int i = batch.first_command; i < end_command; i++) {
- Item::Command *command = p_commands[i];
+ if (material != prev_material) {
+ RasterizerStorageGLES3::Shader *shader_ptr = NULL;
- switch (command->type) {
-#if 0
- case Item::Command::TYPE_LINE: {
- Item::CommandLine *line = static_cast<Item::CommandLine *>(command);
+ if (material_ptr) {
+ shader_ptr = material_ptr->shader;
- _set_texture_rect_mode(false);
+ if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) {
+ shader_ptr = NULL; // not a canvas item shader, don't use.
+ }
+ }
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
+ if (shader_ptr) {
+ if (true) { //check that shader has changed
+ if (shader_ptr->canvas_item.uses_time) {
+ RenderingServerDefault::redraw_request();
+ }
+ //state.canvas_shader.version_bind_shader(shader_ptr->version, CanvasShaderGLES3::MODE_QUAD);
+ state.current_shader_version = shader_ptr->version;
+ }
- _bind_canvas_texture(RID(), RID());
+ int tc = material_ptr->textures.size();
+ Pair<StringName, RID> *textures = material_ptr->textures.ptrw();
+
+ ShaderCompiler::GeneratedCode::Texture *texture_uniforms = shader_ptr->texture_uniforms.ptrw();
+
+ for (int ti = 0; ti < tc; i++) {
+ glActiveTexture(GL_TEXTURE0 + ti);
+
+ RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(textures[ti].second);
+
+ if (!t) {
+ switch (texture_uniforms[i].hint) {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
+ case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
+ glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
+ glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex);
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+ } break;
+ default: {
+ glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+ } break;
+ }
+
+ continue;
+ }
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, line->color.components);
+ //Set texture filter and repeat texture_uniforms[i].filter texture_uniforms[i].repeat
- state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
+ if (t->redraw_if_visible) {
+ RenderingServerDefault::redraw_request();
+ }
- if (line->width <= 1) {
- Vector2 verts[2] = {
- Vector2(line->from.x, line->from.y),
- Vector2(line->to.x, line->to.y)
- };
+ t = t->get_ptr();
-#ifdef GLES_OVER_GL
- if (line->antialiased)
- glEnable(GL_LINE_SMOOTH);
+#ifdef TOOLS_ENABLED
+ if (t->detect_normal && texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) {
+ t->detect_normal(t->detect_normal_ud);
+ }
#endif
- _draw_gui_primitive(2, verts, NULL, NULL);
+ if (t->render_target)
+ t->render_target->used_in_frame = true;
-#ifdef GLES_OVER_GL
- if (line->antialiased)
- glDisable(GL_LINE_SMOOTH);
-#endif
- } else {
- Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5;
-
- Vector2 verts[4] = {
- line->from - t,
- line->from + t,
- line->to + t,
- line->to - t
- };
-
- _draw_gui_primitive(4, verts, NULL, NULL);
-#ifdef GLES_OVER_GL
- if (line->antialiased) {
- glEnable(GL_LINE_SMOOTH);
- for (int j = 0; j < 4; j++) {
- Vector2 vertsl[2] = {
- verts[j],
- verts[(j + 1) % 4],
- };
- _draw_gui_primitive(2, vertsl, NULL, NULL);
- }
- glDisable(GL_LINE_SMOOTH);
- }
-#endif
- }
- } break;
-#endif
- case Item::Command::TYPE_PRIMITIVE: {
- Item::CommandPrimitive *pr = static_cast<Item::CommandPrimitive *>(command);
-
- switch (pr->point_count) {
- case 2: {
- _legacy_draw_line(pr, p_material);
- } break;
- default: {
- _legacy_draw_primitive(pr, p_material);
- } break;
- }
-
- } break;
-
- case Item::Command::TYPE_RECT: {
- Item::CommandRect *r = static_cast<Item::CommandRect *>(command);
- _bind_quad_buffer();
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, r->modulate.components);
-
- bool can_tile = true;
-
- // we will take account of render target textures which need to be drawn upside down
- // quirk of opengl
- bool upside_down = r->flags & CANVAS_RECT_FLIP_V;
-
- // very inefficient, improve this
- if (r->texture.is_valid()) {
- RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(r->texture);
-
- if (texture) {
- if (texture->is_upside_down())
- upside_down = true;
- }
- }
-
- if (r->texture.is_valid() && r->flags & CANVAS_RECT_TILE && !storage->config.support_npot_repeat_mipmap) {
- // workaround for when setting tiling does not work due to hardware limitation
-
- RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(r->texture);
-
- if (texture) {
- texture = texture->get_ptr();
-
- if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, true);
- can_tile = false;
- }
- }
- }
-
- // On some widespread Nvidia cards, the normal draw method can produce some
- // flickering in draw_rect and especially TileMap rendering (tiles randomly flicker).
- // See GH-9913.
- // To work it around, we use a simpler draw method which does not flicker, but gives
- // a non negligible performance hit, so it's opt-in (GH-24466).
- if (use_nvidia_rect_workaround) {
- // are we using normal maps, if so we want to use light angle
- bool send_light_angles = false;
-
- // only need to use light angles when normal mapping
- // otherwise we can use the default shader
- if (state.current_normal != RID()) {
- send_light_angles = true;
- }
-
- _set_texture_rect_mode(false, send_light_angles);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- Vector2 points[4] = {
- r->rect.position,
- r->rect.position + Vector2(r->rect.size.x, 0.0),
- r->rect.position + r->rect.size,
- r->rect.position + Vector2(0.0, r->rect.size.y),
- };
-
- if (r->rect.size.x < 0) {
- SWAP(points[0], points[1]);
- SWAP(points[2], points[3]);
- }
- if (r->rect.size.y < 0) {
- SWAP(points[0], points[3]);
- SWAP(points[1], points[2]);
- }
-
- // FTODO
- //RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(r->texture, r->normal_map);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(r->texture, RID());
-
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
-
- Rect2 src_rect = (r->flags & CANVAS_RECT_REGION) ? Rect2(r->source.position * texpixel_size, r->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
-
- Vector2 uvs[4] = {
- src_rect.position,
- src_rect.position + Vector2(src_rect.size.x, 0.0),
- src_rect.position + src_rect.size,
- src_rect.position + Vector2(0.0, src_rect.size.y),
- };
-
- // for encoding in light angle
- bool flip_h = false;
- bool flip_v = false;
-
- if (r->flags & CANVAS_RECT_TRANSPOSE) {
- SWAP(uvs[1], uvs[3]);
- }
-
- if (r->flags & CANVAS_RECT_FLIP_H) {
- SWAP(uvs[0], uvs[1]);
- SWAP(uvs[2], uvs[3]);
- flip_h = true;
- flip_v = !flip_v;
- }
- if (upside_down) {
- SWAP(uvs[0], uvs[3]);
- SWAP(uvs[1], uvs[2]);
- flip_v = !flip_v;
- }
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
-
- bool untile = false;
-
- if (can_tile && r->flags & CANVAS_RECT_TILE && !(texture->flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT)) {
- texture->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- untile = true;
- }
-
- if (send_light_angles) {
- // for single rects, there is no need to fully utilize the light angle,
- // we only need it to encode flips (horz and vert). But the shader can be reused with
- // batching in which case the angle encodes the transform as well as
- // the flips.
- // Note transpose is NYI. I don't think it worked either with the non-nvidia method.
-
- // if horizontal flip, angle is 180
- float angle = 0.0f;
- if (flip_h)
- angle = Math_PI;
-
- // add 1 (to take care of zero floating point error with sign)
- angle += 1.0f;
-
- // flip if necessary
- if (flip_v)
- angle *= -1.0f;
-
- // light angle must be sent for each vert, instead as a single uniform in the uniform draw method
- // this has the benefit of enabling batching with light angles.
- float light_angles[4] = { angle, angle, angle, angle };
-
- _draw_gui_primitive(4, points, NULL, uvs, light_angles);
- } else {
- _draw_gui_primitive(4, points, NULL, uvs);
- }
-
- if (untile) {
- texture->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- }
- } else {
- static const Vector2 uvs[4] = {
- Vector2(0.0, 0.0),
- Vector2(0.0, 1.0),
- Vector2(1.0, 1.0),
- Vector2(1.0, 0.0),
- };
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, Vector2());
- _draw_gui_primitive(4, points, NULL, uvs);
- }
-
- } else {
- // This branch is better for performance, but can produce flicker on Nvidia, see above comment.
-
- _set_texture_rect_mode(true);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
- _bind_quad_buffer();
-
- // FTODO
- //RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map);
- RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(r->texture, RID());
-
- if (!tex) {
- Rect2 dst_rect = Rect2(r->rect.position, r->rect.size);
-
- if (dst_rect.size.width < 0) {
- dst_rect.position.x += dst_rect.size.width;
- dst_rect.size.width *= -1;
- }
- if (dst_rect.size.height < 0) {
- dst_rect.position.y += dst_rect.size.height;
- dst_rect.size.height *= -1;
- }
-
- state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(0, 0, 1, 1));
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- storage->info.render._2d_draw_call_count++;
- } else {
- bool untile = false;
-
- if (can_tile && r->flags & CANVAS_RECT_TILE && !(tex->flags & RasterizerStorageGLES3::TEXTURE_FLAG_REPEAT)) {
- tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
- untile = true;
- }
-
- Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height);
- Rect2 src_rect = (r->flags & CANVAS_RECT_REGION) ? Rect2(r->source.position * texpixel_size, r->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
-
- Rect2 dst_rect = Rect2(r->rect.position, r->rect.size);
-
- if (dst_rect.size.width < 0) {
- dst_rect.position.x += dst_rect.size.width;
- dst_rect.size.width *= -1;
- }
- if (dst_rect.size.height < 0) {
- dst_rect.position.y += dst_rect.size.height;
- dst_rect.size.height *= -1;
- }
-
- if (r->flags & CANVAS_RECT_FLIP_H) {
- src_rect.size.x *= -1;
- }
-
- if (upside_down) {
- src_rect.size.y *= -1;
- }
+ glBindTexture(t->target, t->tex_id);
+ }
- if (r->flags & CANVAS_RECT_TRANSPOSE) {
- dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
- }
+ } else {
+ //state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD);
+ state.current_shader_version = state.canvas_shader_default_version;
+ }
+ prev_material = material;
+ }
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index);
+ }
+ // Render last command
+ state.end_batch = true;
+ _render_batch(index);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(dst_rect.position.x, dst_rect.position.y, dst_rect.size.x, dst_rect.size.y));
- state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y));
+ canvas_end();
+}
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- storage->info.render._2d_draw_call_count++;
+void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index) {
+ RS::CanvasItemTextureFilter current_filter = state.default_filter;
+ RS::CanvasItemTextureRepeat current_repeat = state.default_repeat;
- if (untile) {
- tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
- }
- }
+ if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
+ current_filter = p_item->texture_filter;
+ }
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
+ if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
+ current_repeat = p_item->texture_repeat;
+ }
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_FORCE_REPEAT, false);
+ Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
+ Transform2D draw_transform; // Used by transform command
- } break;
- case Item::Command::TYPE_NINEPATCH: {
- Item::CommandNinePatch *np = static_cast<Item::CommandNinePatch *>(command);
+ Color base_color = p_item->final_modulate;
- _set_texture_rect_mode(false);
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
- _bind_quad_buffer();
+ uint32_t base_flags = 0;
- glDisableVertexAttribArray(RS::ARRAY_COLOR);
- glVertexAttrib4fv(RS::ARRAY_COLOR, np->color.components);
+ RID last_texture;
+ Size2 texpixel_size;
- // FTODO
- //RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(np->texture, np->normal_map);
- RasterizerStorageGLES3::Texture *tex = _bind_canvas_texture(np->texture, RID());
+ bool skipping = false;
- if (!tex) {
- // FIXME: Handle textureless ninepatch gracefully
- WARN_PRINT("NinePatch without texture not supported yet in OpenGL backend, skipping.");
- continue;
- }
- if (tex->width == 0 || tex->height == 0) {
- WARN_PRINT("Cannot set empty texture to NinePatch.");
- continue;
- }
+ const Item::Command *c = p_item->commands;
+ while (c) {
+ if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
+ c = c->next;
+ continue;
+ }
- Size2 texpixel_size(1.0 / tex->width, 1.0 / tex->height);
+ _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
+
+ for (int i = 0; i < 4; i++) {
+ state.instance_data_array[r_index].modulation[i] = 0.0;
+ state.instance_data_array[r_index].ninepatch_margins[i] = 0.0;
+ state.instance_data_array[r_index].src_rect[i] = 0.0;
+ state.instance_data_array[r_index].dst_rect[i] = 0.0;
+ state.instance_data_array[r_index].lights[i] = uint32_t(0);
+ }
+ state.instance_data_array[r_index].flags = base_flags;
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
- // state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ state.instance_data_array[r_index].pad[0] = 0.0;
+ state.instance_data_array[r_index].pad[1] = 0.0;
- Rect2 source = np->source;
- if (source.size.x == 0 && source.size.y == 0) {
- source.size.x = tex->width;
- source.size.y = tex->height;
- }
+ state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
- float screen_scale = 1.0;
+ switch (c->type) {
+ case Item::Command::TYPE_RECT: {
+ const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
- if ((bdata.settings_ninepatch_mode == 1) && (source.size.x != 0) && (source.size.y != 0)) {
- screen_scale = MIN(np->rect.size.x / source.size.x, np->rect.size.y / source.size.y);
- screen_scale = MIN(1.0, screen_scale);
- }
+ if (rect->flags & CANVAS_RECT_TILE) {
+ current_repeat = RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED;
+ }
- // prepare vertex buffer
+ if (rect->texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_RECT) {
+ state.end_batch = true;
+ _render_batch(r_index);
- // this buffer contains [ POS POS UV UV ] *
+ state.current_primitive_points = 0;
+ state.current_command = Item::Command::TYPE_RECT;
+ }
+ _bind_canvas_texture(rect->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size);
+ state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_QUAD);
- float buffer[16 * 2 + 16 * 2];
+ Rect2 src_rect;
+ Rect2 dst_rect;
- {
- // first row
+ if (rect->texture != RID()) {
+ src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
+ dst_rect = Rect2(rect->rect.position, rect->rect.size);
- buffer[(0 * 4 * 4) + 0] = np->rect.position.x;
- buffer[(0 * 4 * 4) + 1] = np->rect.position.y;
+ if (dst_rect.size.width < 0) {
+ dst_rect.position.x += dst_rect.size.width;
+ dst_rect.size.width *= -1;
+ }
+ if (dst_rect.size.height < 0) {
+ dst_rect.position.y += dst_rect.size.height;
+ dst_rect.size.height *= -1;
+ }
- buffer[(0 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
- buffer[(0 * 4 * 4) + 3] = source.position.y * texpixel_size.y;
+ if (rect->flags & CANVAS_RECT_FLIP_H) {
+ src_rect.size.x *= -1;
+ }
- buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale;
- buffer[(0 * 4 * 4) + 5] = np->rect.position.y;
+ if (rect->flags & CANVAS_RECT_FLIP_V) {
+ src_rect.size.y *= -1;
+ }
- buffer[(0 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x;
- buffer[(0 * 4 * 4) + 7] = source.position.y * texpixel_size.y;
+ if (rect->flags & CANVAS_RECT_TRANSPOSE) {
+ dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
+ }
- buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale;
- buffer[(0 * 4 * 4) + 9] = np->rect.position.y;
+ if (rect->flags & CANVAS_RECT_CLIP_UV) {
+ state.instance_data_array[r_index].flags |= FLAGS_CLIP_RECT_UV;
+ }
- buffer[(0 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x;
- buffer[(0 * 4 * 4) + 11] = source.position.y * texpixel_size.y;
+ } else {
+ dst_rect = Rect2(rect->rect.position, rect->rect.size);
- buffer[(0 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
- buffer[(0 * 4 * 4) + 13] = np->rect.position.y;
+ if (dst_rect.size.width < 0) {
+ dst_rect.position.x += dst_rect.size.width;
+ dst_rect.size.width *= -1;
+ }
+ if (dst_rect.size.height < 0) {
+ dst_rect.position.y += dst_rect.size.height;
+ dst_rect.size.height *= -1;
+ }
- buffer[(0 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
- buffer[(0 * 4 * 4) + 15] = source.position.y * texpixel_size.y;
+ src_rect = Rect2(0, 0, 1, 1);
+ }
- // second row
+ if (rect->flags & CANVAS_RECT_MSDF) {
+ state.instance_data_array[r_index].flags |= FLAGS_USE_MSDF;
+ state.instance_data_array[r_index].msdf[0] = rect->px_range; // Pixel range.
+ state.instance_data_array[r_index].msdf[1] = rect->outline; // Outline size.
+ state.instance_data_array[r_index].msdf[2] = 0.f; // Reserved.
+ state.instance_data_array[r_index].msdf[3] = 0.f; // Reserved.
+ }
- buffer[(1 * 4 * 4) + 0] = np->rect.position.x;
- buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale;
+ state.instance_data_array[r_index].modulation[0] = rect->modulate.r * base_color.r;
+ state.instance_data_array[r_index].modulation[1] = rect->modulate.g * base_color.g;
+ state.instance_data_array[r_index].modulation[2] = rect->modulate.b * base_color.b;
+ state.instance_data_array[r_index].modulation[3] = rect->modulate.a * base_color.a;
+
+ state.instance_data_array[r_index].src_rect[0] = src_rect.position.x;
+ state.instance_data_array[r_index].src_rect[1] = src_rect.position.y;
+ state.instance_data_array[r_index].src_rect[2] = src_rect.size.width;
+ state.instance_data_array[r_index].src_rect[3] = src_rect.size.height;
+
+ state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x;
+ state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y;
+ state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width;
+ state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height;
+ //_render_batch(r_index);
+ r_index++;
+ if (r_index >= state.max_instances_per_batch - 1) {
+ //r_index--;
+ state.end_batch = true;
+ _render_batch(r_index);
+ }
+ } break;
- buffer[(1 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
- buffer[(1 * 4 * 4) + 3] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y;
+ case Item::Command::TYPE_NINEPATCH: {
+ /*
+ const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c);
- buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale;
- buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale;
+ //bind pipeline
+ {
+ RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_NINEPATCH].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
+ RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
+ }
- buffer[(1 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x;
- buffer[(1 * 4 * 4) + 7] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y;
+ //bind textures
- buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale;
- buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale;
+ _bind_canvas_texture(p_draw_list, np->texture, current_filter, current_repeat, index, last_texture, texpixel_size);
- buffer[(1 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x;
- buffer[(1 * 4 * 4) + 11] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y;
+ Rect2 src_rect;
+ Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y);
- buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
- buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[SIDE_TOP] * screen_scale;
+ if (np->texture == RID()) {
+ texpixel_size = Size2(1, 1);
+ src_rect = Rect2(0, 0, 1, 1);
- buffer[(1 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
- buffer[(1 * 4 * 4) + 15] = (source.position.y + np->margin[SIDE_TOP]) * texpixel_size.y;
+ } else {
+ if (np->source != Rect2()) {
+ src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height);
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = 1.0 / np->source.size.width;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = 1.0 / np->source.size.height;
- // third row
+ } else {
+ src_rect = Rect2(0, 0, 1, 1);
+ }
+ }
- buffer[(2 * 4 * 4) + 0] = np->rect.position.x;
- buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale;
+ state.instance_data_array[r_index].modulation[0] = np->color.r * base_color.r;
+ state.instance_data_array[r_index].modulation[1] = np->color.g * base_color.g;
+ state.instance_data_array[r_index].modulation[2] = np->color.b * base_color.b;
+ state.instance_data_array[r_index].modulation[3] = np->color.a * base_color.a;
- buffer[(2 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
- buffer[(2 * 4 * 4) + 3] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y;
+ state.instance_data_array[r_index].src_rect[0] = src_rect.position.x;
+ state.instance_data_array[r_index].src_rect[1] = src_rect.position.y;
+ state.instance_data_array[r_index].src_rect[2] = src_rect.size.width;
+ state.instance_data_array[r_index].src_rect[3] = src_rect.size.height;
- buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale;
- buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale;
+ state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x;
+ state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y;
+ state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width;
+ state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height;
- buffer[(2 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x;
- buffer[(2 * 4 * 4) + 7] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y;
+ state.instance_data_array[r_index].flags |= int(np->axis_x) << FLAGS_NINEPATCH_H_MODE_SHIFT;
+ state.instance_data_array[r_index].flags |= int(np->axis_y) << FLAGS_NINEPATCH_V_MODE_SHIFT;
- buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale;
- buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale;
+ if (np->draw_center) {
+ state.instance_data_array[r_index].flags |= FLAGS_NINEPACH_DRAW_CENTER;
+ }
- buffer[(2 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x;
- buffer[(2 * 4 * 4) + 11] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y;
+ state.instance_data_array[r_index].ninepatch_margins[0] = np->margin[SIDE_LEFT];
+ state.instance_data_array[r_index].ninepatch_margins[1] = np->margin[SIDE_TOP];
+ state.instance_data_array[r_index].ninepatch_margins[2] = np->margin[SIDE_RIGHT];
+ state.instance_data_array[r_index].ninepatch_margins[3] = np->margin[SIDE_BOTTOM];
- buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
- buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[SIDE_BOTTOM] * screen_scale;
+ RD::get_singleton()->draw_list_set_state.instance_data_array[r_index](p_draw_list, &state.instance_data_array[r_index], sizeof(PushConstant));
+ RD::get_singleton()->draw_list_bind_index_array(p_draw_list, shader.quad_index_array);
+ RD::get_singleton()->draw_list_draw(p_draw_list, true);
- buffer[(2 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
- buffer[(2 * 4 * 4) + 15] = (source.position.y + source.size.y - np->margin[SIDE_BOTTOM]) * texpixel_size.y;
+ // Restore if overridden.
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = texpixel_size.x;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = texpixel_size.y;
+*/
+ } break;
- // fourth row
+ case Item::Command::TYPE_POLYGON: {
+ const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
- buffer[(3 * 4 * 4) + 0] = np->rect.position.x;
- buffer[(3 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y;
+ PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id);
+ ERR_CONTINUE(!pb);
- buffer[(3 * 4 * 4) + 2] = source.position.x * texpixel_size.x;
- buffer[(3 * 4 * 4) + 3] = (source.position.y + source.size.y) * texpixel_size.y;
+ if (polygon->texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_POLYGON) {
+ state.end_batch = true;
+ _render_batch(r_index);
- buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[SIDE_LEFT] * screen_scale;
- buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y;
+ state.current_primitive_points = 0;
+ state.current_command = Item::Command::TYPE_POLYGON;
+ }
+ _bind_canvas_texture(polygon->texture, current_filter, current_repeat, r_index, last_texture, texpixel_size);
+ state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_ATTRIBUTES);
+
+ state.current_primitive = polygon->primitive;
+ state.instance_data_array[r_index].modulation[0] = base_color.r;
+ state.instance_data_array[r_index].modulation[1] = base_color.g;
+ state.instance_data_array[r_index].modulation[2] = base_color.b;
+ state.instance_data_array[r_index].modulation[3] = base_color.a;
+
+ for (int j = 0; j < 4; j++) {
+ state.instance_data_array[r_index].src_rect[j] = 0;
+ state.instance_data_array[r_index].dst_rect[j] = 0;
+ state.instance_data_array[r_index].ninepatch_margins[j] = 0;
+ }
- buffer[(3 * 4 * 4) + 6] = (source.position.x + np->margin[SIDE_LEFT]) * texpixel_size.x;
- buffer[(3 * 4 * 4) + 7] = (source.position.y + source.size.y) * texpixel_size.y;
+ // If the previous operation is not done yet, allocated a new buffer
+ GLint syncStatus;
+ glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus);
+ if (syncStatus == GL_UNSIGNALED) {
+ _allocate_instance_data_buffer();
+ } else {
+ glDeleteSync(state.fences[state.current_buffer]);
+ }
- buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[SIDE_RIGHT] * screen_scale;
- buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y;
+ glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]);
+#ifdef JAVASCRIPT_ENABLED
+ //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData), &state.instance_data_array[0], GL_DYNAMIC_DRAW);
+#else
+ void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+ memcpy(ubo, &state.instance_data_array[0], sizeof(InstanceData));
+ glUnmapBuffer(GL_UNIFORM_BUFFER);
+#endif
+ glBindVertexArray(pb->vertex_array);
- buffer[(3 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[SIDE_RIGHT]) * texpixel_size.x;
- buffer[(3 * 4 * 4) + 11] = (source.position.y + source.size.y) * texpixel_size.y;
+ static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
- buffer[(3 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x;
- buffer[(3 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y;
+ if (pb->index_buffer != 0) {
+ glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, 0);
+ } else {
+ glDrawArrays(prim[polygon->primitive], 0, pb->count);
+ }
+ glBindVertexArray(0);
+ state.fences[state.current_buffer] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
- buffer[(3 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x;
- buffer[(3 * 4 * 4) + 15] = (source.position.y + source.size.y) * texpixel_size.y;
- }
+ state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size();
+ } break;
- glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, buffer, _buffer_upload_usage_flag);
+ case Item::Command::TYPE_PRIMITIVE: {
+ const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
+ if (last_texture != default_canvas_texture || state.current_primitive_points != primitive->point_count || state.current_command != Item::Command::TYPE_PRIMITIVE) {
+ state.end_batch = true;
+ _render_batch(r_index);
+ state.current_primitive_points = primitive->point_count;
+ state.current_command = Item::Command::TYPE_PRIMITIVE;
+ }
+ _bind_canvas_texture(RID(), current_filter, current_repeat, r_index, last_texture, texpixel_size);
+ state.canvas_shader.version_bind_shader(state.current_shader_version, CanvasShaderGLES3::MODE_PRIMITIVE);
+
+ for (uint32_t j = 0; j < MIN(3, primitive->point_count); j++) {
+ state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x;
+ state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j].y;
+ state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j].x;
+ state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j].y;
+ Color col = primitive->colors[j] * base_color;
+ state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
+ state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
+ }
+ r_index++;
+ if (primitive->point_count == 4) {
+ // Reset base data
+ _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
+
+ state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
+
+ for (uint32_t j = 0; j < 3; j++) {
+ //second half of triangle
+ state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j + 1].x;
+ state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j + 1].y;
+ state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j + 1].x;
+ state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j + 1].y;
+ Color col = primitive->colors[j + 1] * base_color;
+ state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
+ state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
+ }
+ r_index++;
+ }
+ if (r_index >= state.max_instances_per_batch - 1) {
+ //r_index--;
+ state.end_batch = true;
+ _render_batch(r_index);
+ }
+ } break;
- //glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
+ case Item::Command::TYPE_MESH:
+ case Item::Command::TYPE_MULTIMESH:
+ case Item::Command::TYPE_PARTICLES: {
+ /*
+ RID mesh;
+ RID mesh_instance;
+ RID texture;
+ Color modulate(1, 1, 1, 1);
+ int instance_count = 1;
+
+ if (c->type == Item::Command::TYPE_MESH) {
+ const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c);
+ mesh = m->mesh;
+ mesh_instance = m->mesh_instance;
+ texture = m->texture;
+ modulate = m->modulate;
+ _update_transform_2d_to_mat2x3(base_transform * draw_transform * m->transform, state.instance_data_array[r_index].world);
+ } else if (c->type == Item::Command::TYPE_MULTIMESH) {
+ const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(c);
+ RID multimesh = mm->multimesh;
+ mesh = storage->multimesh_get_mesh(multimesh);
+ texture = mm->texture;
+
+ if (storage->multimesh_get_transform_format(multimesh) != RS::MULTIMESH_TRANSFORM_2D) {
+ break;
+ }
- //glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), NULL);
- glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), CAST_INT_TO_UCHAR_PTR((sizeof(float) * 2)));
+ instance_count = storage->multimesh_get_instances_to_draw(multimesh);
- //glDrawElements(GL_TRIANGLES, 18 * 3 - (np->draw_center ? 0 : 6), GL_UNSIGNED_SHORT, NULL);
+ if (instance_count == 0) {
+ break;
+ }
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- storage->info.render._2d_draw_call_count++;
+ state.instance_data_array[r_index].flags |= 1; //multimesh, trails disabled
+ if (storage->multimesh_uses_colors(multimesh)) {
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_COLORS;
+ }
+ if (storage->multimesh_uses_custom_data(multimesh)) {
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
+ }
+ }
- } break;
-#if 0
- case Item::Command::TYPE_CIRCLE: {
- Item::CommandCircle *circle = static_cast<Item::CommandCircle *>(command);
+ // TODO: implement particles here
- _set_texture_rect_mode(false);
+ if (mesh.is_null()) {
+ break;
+ }
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
+ if (texture != last_texture || state.current_primitive_points != 0 || state.current_command != Item::Command::TYPE_PRIMITIVE) {
+ state.end_batch = true;
+ _render_batch(r_index);
+ state.current_primitive_points = 0;
+ state.current_command = c->type;
+ }
- static const int num_points = 32;
+ _bind_canvas_texture(texture, current_filter, current_repeat, r_index, last_texture, texpixel_size);
- Vector2 points[num_points + 1];
- points[num_points] = circle->pos;
+ uint32_t surf_count = storage->mesh_get_surface_count(mesh);
- int indices[num_points * 3];
+ state.instance_data_array[r_index].modulation[0] = base_color.r * modulate.r;
+ state.instance_data_array[r_index].modulation[1] = base_color.g * modulate.g;
+ state.instance_data_array[r_index].modulation[2] = base_color.b * modulate.b;
+ state.instance_data_array[r_index].modulation[3] = base_color.a * modulate.a;
- for (int j = 0; j < num_points; j++) {
- points[j] = circle->pos + Vector2(Math::sin(j * Math_PI * 2.0 / num_points), Math::cos(j * Math_PI * 2.0 / num_points)) * circle->radius;
- indices[j * 3 + 0] = j;
- indices[j * 3 + 1] = (j + 1) % num_points;
- indices[j * 3 + 2] = num_points;
- }
+ for (int j = 0; j < 4; j++) {
+ state.instance_data_array[r_index].src_rect[j] = 0;
+ state.instance_data_array[r_index].dst_rect[j] = 0;
+ state.instance_data_array[r_index].ninepatch_margins[j] = 0;
+ }
- _bind_canvas_texture(RID(), RID());
+ for (uint32_t j = 0; j < surf_count; j++) {
+ RS::SurfaceData *surface = storage->mesh_get_surface(mesh, j);
- _draw_polygon(indices, num_points * 3, num_points + 1, points, NULL, &circle->color, true);
- } break;
-#endif
- case Item::Command::TYPE_POLYGON: {
- Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(command);
- //const PolyData &pd = _polydata[polygon->polygon.polygon_id];
-
- switch (polygon->primitive) {
- case RS::PRIMITIVE_TRIANGLES: {
- _legacy_draw_poly_triangles(polygon, p_material);
- } break;
- default:
- break;
- }
-
- } break;
-#if 0
- case Item::Command::TYPE_MESH: {
- Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(command);
-
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mesh->texture, mesh->normal_map);
-
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- }
+ RS::PrimitiveType primitive = storage->mesh_surface_get_primitive(surface);
+ ERR_CONTINUE(primitive < 0 || primitive >= RS::PRIMITIVE_MAX);
- RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.get_or_null(mesh->mesh);
- if (mesh_data) {
- for (int j = 0; j < mesh_data->surfaces.size(); j++) {
- RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j];
- // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
-
- glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id);
-
- if (s->index_array_len > 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
- }
-
- for (int k = 0; k < RS::ARRAY_MAX - 1; k++) {
- if (s->attribs[k].enabled) {
- glEnableVertexAttribArray(k);
- glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset));
- } else {
- glDisableVertexAttribArray(k);
- switch (k) {
- case RS::ARRAY_NORMAL: {
- glVertexAttrib4f(RS::ARRAY_NORMAL, 0.0, 0.0, 1, 1);
- } break;
- case RS::ARRAY_COLOR: {
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
-
- } break;
- default: {
- }
- }
- }
- }
-
- if (s->index_array_len > 0) {
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
- } else {
- glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
- }
- }
-
- for (int j = 1; j < RS::ARRAY_MAX - 1; j++) {
- glDisableVertexAttribArray(j);
- }
- }
-
- storage->info.render._2d_draw_call_count++;
- } break;
- case Item::Command::TYPE_MULTIMESH: {
- Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(command);
-
- RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.get_or_null(mmesh->multimesh);
-
- if (!multi_mesh)
- break;
-
- RasterizerStorageGLES3::Mesh *mesh_data = storage->mesh_owner.get_or_null(multi_mesh->mesh);
-
- if (!mesh_data)
- break;
-
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != RS::MULTIMESH_CUSTOM_DATA_NONE);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, true);
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map);
-
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- }
-
- //reset shader and force rebind
-
- int amount = MIN(multi_mesh->size, multi_mesh->visible_instances);
-
- if (amount == -1) {
- amount = multi_mesh->size;
- }
-
- int stride = multi_mesh->color_floats + multi_mesh->custom_data_floats + multi_mesh->xform_floats;
-
- int color_ofs = multi_mesh->xform_floats;
- int custom_data_ofs = color_ofs + multi_mesh->color_floats;
-
- // drawing
-
- const float *base_buffer = multi_mesh->data.ptr();
-
- for (int j = 0; j < mesh_data->surfaces.size(); j++) {
- RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j];
- // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
-
- //bind buffers for mesh surface
- glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id);
-
- if (s->index_array_len > 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
- }
-
- for (int k = 0; k < RS::ARRAY_MAX - 1; k++) {
- if (s->attribs[k].enabled) {
- glEnableVertexAttribArray(k);
- glVertexAttribPointer(s->attribs[k].index, s->attribs[k].size, s->attribs[k].type, s->attribs[k].normalized, s->attribs[k].stride, CAST_INT_TO_UCHAR_PTR(s->attribs[k].offset));
- } else {
- glDisableVertexAttribArray(k);
- switch (k) {
- case RS::ARRAY_NORMAL: {
- glVertexAttrib4f(RS::ARRAY_NORMAL, 0.0, 0.0, 1, 1);
- } break;
- case RS::ARRAY_COLOR: {
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
-
- } break;
- default: {
- }
- }
- }
- }
-
- for (int k = 0; k < amount; k++) {
- const float *buffer = base_buffer + k * stride;
-
- {
- glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 0, &buffer[0]);
- glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 1, &buffer[4]);
- if (multi_mesh->transform_format == RS::MULTIMESH_TRANSFORM_3D) {
- glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 2, &buffer[8]);
- } else {
- glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 2, 0.0, 0.0, 1.0, 0.0);
- }
- }
-
- if (multi_mesh->color_floats) {
- if (multi_mesh->color_format == RS::MULTIMESH_COLOR_8BIT) {
- uint8_t *color_data = (uint8_t *)(buffer + color_ofs);
- glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, color_data[0] / 255.0, color_data[1] / 255.0, color_data[2] / 255.0, color_data[3] / 255.0);
- } else {
- glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs);
- }
- } else {
- glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, 1.0, 1.0, 1.0, 1.0);
- }
-
- if (multi_mesh->custom_data_floats) {
- if (multi_mesh->custom_data_format == RS::MULTIMESH_CUSTOM_DATA_8BIT) {
- uint8_t *custom_data = (uint8_t *)(buffer + custom_data_ofs);
- glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 4, custom_data[0] / 255.0, custom_data[1] / 255.0, custom_data[2] / 255.0, custom_data[3] / 255.0);
- } else {
- glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 4, buffer + custom_data_ofs);
- }
- }
-
- if (s->index_array_len > 0) {
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
- } else {
- glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
- }
- }
- }
-
- // LIGHT ANGLE PR replaced USE_INSTANCE_CUSTOM line with below .. think it was a typo,
- // but just in case, made this note.
- //_set_texture_rect_mode(false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCE_CUSTOM, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_INSTANCING, false);
-
- storage->info.render._2d_draw_call_count++;
- } break;
- case Item::Command::TYPE_POLYLINE: {
- Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(command);
-
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- _bind_canvas_texture(RID(), RID());
-
- if (pline->triangles.size()) {
- _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1);
-#ifdef GLES_OVER_GL
- glEnable(GL_LINE_SMOOTH);
- if (pline->multiline) {
- //needs to be different
- } else {
- _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
- }
- glDisable(GL_LINE_SMOOTH);
-#endif
- } else {
-#ifdef GLES_OVER_GL
- if (pline->antialiased)
- glEnable(GL_LINE_SMOOTH);
-#endif
+ glBindVertexArray(surface->vertex_array);
+ static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
- if (pline->multiline) {
- int todo = pline->lines.size() / 2;
- int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4);
- int offset = 0;
-
- while (todo) {
- int to_draw = MIN(max_per_call, todo);
- _draw_generic(GL_LINES, to_draw * 2, &pline->lines.ptr()[offset], NULL, pline->line_colors.size() == 1 ? pline->line_colors.ptr() : &pline->line_colors.ptr()[offset], pline->line_colors.size() == 1);
- todo -= to_draw;
- offset += to_draw * 2;
- }
- } else {
- _draw_generic(GL_LINE_STRIP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1);
- }
-
-#ifdef GLES_OVER_GL
- if (pline->antialiased)
- glDisable(GL_LINE_SMOOTH);
-#endif
- }
- } break;
-
- case Item::Command::TYPE_PRIMITIVE: {
- Item::CommandPrimitive *primitive = static_cast<Item::CommandPrimitive *>(command);
- _set_texture_rect_mode(false);
-
- if (state.canvas_shader.bind()) {
- _set_uniforms();
- state.canvas_shader.use_material((void *)p_material);
- }
-
- ERR_CONTINUE(primitive->points.size() < 1);
-
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map);
-
- if (texture) {
- Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- }
-
- // we need a temporary because this must be nulled out
- // if only a single color specified
- const Color *colors = primitive->colors.ptr();
- if (primitive->colors.size() == 1 && primitive->points.size() > 1) {
- Color c = primitive->colors[0];
- glVertexAttrib4f(RS::ARRAY_COLOR, c.r, c.g, c.b, c.a);
- colors = nullptr;
- } else if (primitive->colors.empty()) {
- glVertexAttrib4f(RS::ARRAY_COLOR, 1, 1, 1, 1);
- }
-#ifdef RASTERIZER_EXTRA_CHECKS
- else {
- RAST_DEV_DEBUG_ASSERT(primitive->colors.size() == primitive->points.size());
- }
-
- if (primitive->uvs.ptr()) {
- RAST_DEV_DEBUG_ASSERT(primitive->uvs.size() == primitive->points.size());
- }
-#endif
+ // Draw directly, no need to batch
+ }
+ */
+ } break;
+ case Item::Command::TYPE_TRANSFORM: {
+ const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
+ draw_transform = transform->xform;
+ } break;
- _draw_gui_primitive(primitive->points.size(), primitive->points.ptr(), colors, primitive->uvs.ptr());
- } break;
-#endif
- case Item::Command::TYPE_TRANSFORM: {
- Item::CommandTransform *transform = static_cast<Item::CommandTransform *>(command);
- state.uniforms.extra_matrix = transform->xform;
- state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, state.uniforms.extra_matrix);
- } break;
-
- case Item::Command::TYPE_PARTICLES: {
- } break;
- case Item::Command::TYPE_CLIP_IGNORE: {
- Item::CommandClipIgnore *ci = static_cast<Item::CommandClipIgnore *>(command);
- if (p_current_clip) {
- if (ci->ignore != r_reclip) {
- if (ci->ignore) {
- glDisable(GL_SCISSOR_TEST);
- r_reclip = true;
- } else {
- glEnable(GL_SCISSOR_TEST);
-
- int x = p_current_clip->final_clip_rect.position.x;
- int y = storage->frame.current_rt->height - (p_current_clip->final_clip_rect.position.y + p_current_clip->final_clip_rect.size.y);
- int w = p_current_clip->final_clip_rect.size.x;
- int h = p_current_clip->final_clip_rect.size.y;
-
- // FTODO
- // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP])
- // y = p_current_clip->final_clip_rect.position.y;
-
- glScissor(x, y, w, h);
-
- r_reclip = false;
- }
- }
- }
-
- } break;
- default: {
- // FIXME: Proper error handling if relevant
- //print_line("other");
- } break;
+ case Item::Command::TYPE_CLIP_IGNORE: {
+ /*
+ const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c);
+ if (current_clip) {
+ if (ci->ignore != reclip) {
+ if (ci->ignore) {
+ RD::get_singleton()->draw_list_disable_scissor(p_draw_list);
+ reclip = true;
+ } else {
+ RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect);
+ reclip = false;
+ }
}
}
+ */
+ } break;
+ case Item::Command::TYPE_ANIMATION_SLICE: {
+ /*
+ const Item::CommandAnimationSlice *as = static_cast<const Item::CommandAnimationSlice *>(c);
+ double current_time = RendererCompositorRD::singleton->get_total_time();
+ double local_time = Math::fposmod(current_time - as->offset, as->animation_length);
+ skipping = !(local_time >= as->slice_begin && local_time < as->slice_end);
+
+ RenderingServerDefault::redraw_request(); // animation visible means redraw request
+ */
+ } break;
+ }
- } // default
- break;
+ c = c->next;
+ }
+}
+
+void RasterizerCanvasGLES3::_render_batch(uint32_t &r_index) {
+ if (state.end_batch && r_index > 0) {
+ // If the previous operation is not done yet, allocate a new buffer
+ GLint syncStatus;
+ glGetSynciv(state.fences[state.current_buffer], GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus);
+ if (syncStatus == GL_UNSIGNALED) {
+ _allocate_instance_data_buffer();
+ } else {
+ glDeleteSync(state.fences[state.current_buffer]);
}
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, 3, state.canvas_instance_data_buffers[state.current_buffer]);
+#ifdef JAVASCRIPT_ENABLED
+ //WebGL 2.0 does not support mapping buffers, so use slow glBufferData instead
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * r_index, state.instance_data_array, GL_DYNAMIC_DRAW);
+#else
+ void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(InstanceData) * r_index, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+ memcpy(ubo, state.instance_data_array, sizeof(InstanceData) * r_index);
+ glUnmapBuffer(GL_UNIFORM_BUFFER);
+#endif
+ glBindVertexArray(data.canvas_quad_array);
+ if (state.current_primitive_points == 0) {
+ glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, r_index);
+ } else {
+ static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLES };
+ glDrawArraysInstanced(prim[state.current_primitive_points], 0, state.current_primitive_points, r_index);
+ }
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+
+ state.fences[state.current_buffer] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size();
+ state.end_batch = false;
+ //copy the new data into the base of the batch
+ for (int i = 0; i < 4; i++) {
+ state.instance_data_array[0].modulation[i] = state.instance_data_array[r_index].modulation[i];
+ state.instance_data_array[0].ninepatch_margins[i] = state.instance_data_array[r_index].ninepatch_margins[i];
+ state.instance_data_array[0].src_rect[i] = state.instance_data_array[r_index].src_rect[i];
+ state.instance_data_array[0].dst_rect[i] = state.instance_data_array[r_index].dst_rect[i];
+ state.instance_data_array[0].lights[i] = state.instance_data_array[r_index].lights[i];
+ }
+ state.instance_data_array[0].flags = state.instance_data_array[r_index].flags;
+ state.instance_data_array[0].color_texture_pixel_size[0] = state.instance_data_array[r_index].color_texture_pixel_size[0];
+ state.instance_data_array[0].color_texture_pixel_size[1] = state.instance_data_array[r_index].color_texture_pixel_size[1];
+
+ state.instance_data_array[0].pad[0] = state.instance_data_array[r_index].pad[0];
+ state.instance_data_array[0].pad[1] = state.instance_data_array[r_index].pad[1];
+ for (int i = 0; i < 6; i++) {
+ state.instance_data_array[0].world[i] = state.instance_data_array[r_index].world[i];
+ }
+
+ r_index = 0;
}
}
-void RasterizerCanvasGLES3::canvas_end() {
- batch_canvas_end();
- RasterizerCanvasBaseGLES3::canvas_end();
+// TODO maybe dont use
+void RasterizerCanvasGLES3::_end_batch(uint32_t &r_index) {
+ for (int i = 0; i < 4; i++) {
+ state.instance_data_array[r_index].modulation[i] = 0.0;
+ state.instance_data_array[r_index].ninepatch_margins[i] = 0.0;
+ state.instance_data_array[r_index].src_rect[i] = 0.0;
+ state.instance_data_array[r_index].dst_rect[i] = 0.0;
+ }
+ state.instance_data_array[r_index].flags = uint32_t(0);
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
+
+ state.instance_data_array[r_index].pad[0] = 0.0;
+ state.instance_data_array[r_index].pad[1] = 0.0;
+
+ state.instance_data_array[r_index].lights[0] = uint32_t(0);
+ state.instance_data_array[r_index].lights[1] = uint32_t(0);
+ state.instance_data_array[r_index].lights[2] = uint32_t(0);
+ state.instance_data_array[r_index].lights[3] = uint32_t(0);
}
-void RasterizerCanvasGLES3::canvas_begin() {
- batch_canvas_begin();
- RasterizerCanvasBaseGLES3::canvas_begin();
+RID RasterizerCanvasGLES3::light_create() {
+ return RID();
}
-void RasterizerCanvasGLES3::canvas_render_items_begin(const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
- batch_canvas_render_items_begin(p_modulate, p_light, p_base_transform);
+void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) {
}
-void RasterizerCanvasGLES3::canvas_render_items_end() {
- batch_canvas_render_items_end();
+void RasterizerCanvasGLES3::light_set_use_shadow(RID p_rid, bool p_enable) {
}
-void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
- storage->frame.current_rt = nullptr;
+void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
+}
- // first set the current render target
- storage->_set_current_render_target(p_to_render_target);
+void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) {
+}
- // binds the render target (framebuffer)
- canvas_begin();
+void RasterizerCanvasGLES3::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
+}
- canvas_render_items_begin(p_modulate, p_light_list, p_canvas_transform);
- canvas_render_items_internal(p_item_list, 0, p_modulate, p_light_list, p_canvas_transform);
- canvas_render_items_end();
+RID RasterizerCanvasGLES3::occluder_polygon_create() {
+ return RID();
+}
- canvas_end();
+void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
+}
- // not sure why these are needed to get frame to render?
- storage->_set_current_render_target(RID());
- // storage->frame.current_rt = nullptr;
- // canvas_begin();
- // canvas_end();
+void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
}
-void RasterizerCanvasGLES3::canvas_render_items_internal(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
- batch_canvas_render_items(p_item_list, p_z, p_modulate, p_light, p_base_transform);
+void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) {
+}
- //glClearColor(Math::randf(), 0, 1, 1);
+bool RasterizerCanvasGLES3::free(RID p_rid) {
+ return true;
}
-void RasterizerCanvasGLES3::canvas_render_items_implementation(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
- // parameters are easier to pass around in a structure
- RenderItemState ris;
- ris.item_group_z = p_z;
- ris.item_group_modulate = p_modulate;
- ris.item_group_light = p_light;
- ris.item_group_base_transform = p_base_transform;
+void RasterizerCanvasGLES3::update() {
+}
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false);
+void RasterizerCanvasGLES3::canvas_begin() {
+ state.using_transparent_rt = false;
- state.current_tex = RID();
- state.current_tex_ptr = NULL;
- state.current_normal = RID();
- state.canvas_texscreen_used = false;
+ if (storage->frame.current_rt) {
+ storage->bind_framebuffer(storage->frame.current_rt->fbo);
+ state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT];
+ }
+
+ if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) {
+ const Color &col = storage->frame.current_rt->clear_color;
+ glClearColor(col.r, col.g, col.b, col.a);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ storage->frame.current_rt->clear_requested = false;
+ }
+
+ reset_canvas();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+}
- while (p_item_list) {
- Item *ci = p_item_list;
- _legacy_canvas_render_item(ci, ris);
- p_item_list = p_item_list->next;
+void RasterizerCanvasGLES3::canvas_end() {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
+
+void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size) {
+ if (p_texture == RID()) {
+ p_texture = default_canvas_texture;
}
- if (ris.current_clip) {
- glDisable(GL_SCISSOR_TEST);
+ if (r_last_texture == p_texture) {
+ return; //nothing to do, its the same
}
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, false);
-}
+ state.end_batch = true;
+ _render_batch(r_index);
-// Legacy non-batched implementation for regression testing.
-// Should be removed after testing phase to avoid duplicate codepaths.
-void RasterizerCanvasGLES3::_legacy_canvas_render_item(Item *p_ci, RenderItemState &r_ris) {
- storage->info.render._2d_item_count++;
+ RasterizerStorageGLES3::CanvasTexture *ct = nullptr;
- // defaults
- state.current_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
- state.current_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
+ RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(p_texture);
+
+ if (t) {
+ //regular texture
+ if (!t->canvas_texture) {
+ t->canvas_texture = memnew(RasterizerStorageGLES3::CanvasTexture);
+ t->canvas_texture->diffuse = p_texture;
+ }
- if (p_ci->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
- state.current_filter = p_ci->texture_filter;
+ ct = t->canvas_texture;
+ } else {
+ ct = storage->canvas_texture_owner.get_or_null(p_texture);
}
- if (p_ci->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
- state.current_repeat = p_ci->texture_repeat;
+ if (!ct) {
+ // Invalid Texture RID.
+ _bind_canvas_texture(default_canvas_texture, p_base_filter, p_base_repeat, r_index, r_last_texture, r_texpixel_size);
+ return;
}
- if (r_ris.current_clip != p_ci->final_clip_owner) {
- r_ris.current_clip = p_ci->final_clip_owner;
-
- if (r_ris.current_clip) {
- glEnable(GL_SCISSOR_TEST);
- int y = storage->_dims.rt_height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y);
- // int y = storage->frame.current_rt->height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y);
- // FTODO
- // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP])
- // y = r_ris.current_clip->final_clip_rect.position.y;
- glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height);
-
- // debug VFLIP
- // if ((r_ris.current_clip->final_clip_rect.position.x == 223)
- // && (y == 54)
- // && (r_ris.current_clip->final_clip_rect.size.width == 1383))
- // {
- // glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height);
- // }
+ RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
+ ERR_FAIL_COND(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT);
- } else {
- glDisable(GL_SCISSOR_TEST);
- }
+ RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
+ ERR_FAIL_COND(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
+
+ RasterizerStorageGLES3::Texture *texture = storage->texture_owner.get_or_null(ct->diffuse);
+
+ if (!texture) {
+ state.current_tex = RID();
+ state.current_tex_ptr = NULL;
+ ct->size_cache = Size2i(1, 1);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+
+ } else {
+ texture = texture->get_ptr();
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture->tex_id);
+
+ state.current_tex = ct->diffuse;
+ state.current_tex_ptr = texture;
+ ct->size_cache = Size2i(texture->width, texture->height);
+
+ texture->GLSetFilter(GL_TEXTURE_2D, filter);
+ texture->GLSetRepeat(GL_TEXTURE_2D, repeat);
}
- // TODO: copy back buffer
+ RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.get_or_null(ct->normal_map);
- if (p_ci->copy_back_buffer) {
- if (p_ci->copy_back_buffer->full) {
- _copy_texscreen(Rect2());
- } else {
- _copy_texscreen(p_ci->copy_back_buffer->rect);
- }
+ if (!normal_map) {
+ state.current_normal = RID();
+ ct->use_normal_cache = false;
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+
+ } else {
+ normal_map = normal_map->get_ptr();
+
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
+ glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
+ state.current_normal = ct->normal_map;
+ ct->use_normal_cache = true;
+ texture->GLSetFilter(GL_TEXTURE_2D, filter);
+ texture->GLSetRepeat(GL_TEXTURE_2D, repeat);
}
-#if 0
- RasterizerStorageGLES3::Skeleton *skeleton = NULL;
+ RasterizerStorageGLES3::Texture *specular_map = storage->texture_owner.get_or_null(ct->specular);
- {
- //skeleton handling
- if (p_ci->skeleton.is_valid() && storage->skeleton_owner.owns(p_ci->skeleton)) {
- skeleton = storage->skeleton_owner.get(p_ci->skeleton);
- if (!skeleton->use_2d) {
- skeleton = NULL;
- } else {
- state.skeleton_transform = r_ris.item_group_base_transform * skeleton->base_transform_2d;
- state.skeleton_transform_inverse = state.skeleton_transform.affine_inverse();
- state.skeleton_texture_size = Vector2(skeleton->size * 2, 0);
- }
- }
+ if (!specular_map) {
+ state.current_specular = RID();
+ ct->use_specular_cache = false;
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
- bool use_skeleton = skeleton != NULL;
- if (r_ris.prev_use_skeleton != use_skeleton) {
- r_ris.rebind_shader = true;
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SKELETON, use_skeleton);
- r_ris.prev_use_skeleton = use_skeleton;
- }
+ } else {
+ specular_map = specular_map->get_ptr();
+
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
+ glBindTexture(GL_TEXTURE_2D, specular_map->tex_id);
+ state.current_specular = ct->specular;
+ ct->use_specular_cache = true;
+ texture->GLSetFilter(GL_TEXTURE_2D, filter);
+ texture->GLSetRepeat(GL_TEXTURE_2D, repeat);
+ }
- if (skeleton) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
- glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
- state.using_skeleton = true;
- } else {
- state.using_skeleton = false;
- }
+ if (ct->use_specular_cache) {
+ state.instance_data_array[r_index].flags |= FLAGS_DEFAULT_SPECULAR_MAP_USED;
+ } else {
+ state.instance_data_array[r_index].flags &= ~FLAGS_DEFAULT_SPECULAR_MAP_USED;
}
-#endif
- Item *material_owner = p_ci->material_owner ? p_ci->material_owner : p_ci;
+ if (ct->use_normal_cache) {
+ state.instance_data_array[r_index].flags |= FLAGS_DEFAULT_NORMAL_MAP_USED;
+ } else {
+ state.instance_data_array[r_index].flags &= ~FLAGS_DEFAULT_NORMAL_MAP_USED;
+ }
- RID material = material_owner->material;
- RasterizerStorageGLES3::Material *material_ptr = storage->material_owner.get_or_null(material);
+ state.instance_data_array[r_index].specular_shininess = uint32_t(CLAMP(ct->specular_color.a * 255.0, 0, 255)) << 24;
+ state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.b * 255.0, 0, 255)) << 16;
+ state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.g * 255.0, 0, 255)) << 8;
+ state.instance_data_array[r_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.r * 255.0, 0, 255));
- if (material != r_ris.canvas_last_material || r_ris.rebind_shader) {
- RasterizerStorageGLES3::Shader *shader_ptr = NULL;
+ r_texpixel_size.x = 1.0 / float(ct->size_cache.x);
+ r_texpixel_size.y = 1.0 / float(ct->size_cache.y);
- if (material_ptr) {
- shader_ptr = material_ptr->shader;
+ state.instance_data_array[r_index].color_texture_pixel_size[0] = r_texpixel_size.x;
+ state.instance_data_array[r_index].color_texture_pixel_size[1] = r_texpixel_size.y;
- if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) {
- shader_ptr = NULL; // not a canvas item shader, don't use.
- }
- }
+ r_last_texture = p_texture;
+}
- if (shader_ptr) {
- if (shader_ptr->canvas_item.uses_screen_texture) {
- if (!state.canvas_texscreen_used) {
- //copy if not copied before
- _copy_texscreen(Rect2());
+void RasterizerCanvasGLES3::_set_uniforms() {
+}
- // blend mode will have been enabled so make sure we disable it again later on
- //last_blend_mode = last_blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_DISABLED ? last_blend_mode : -1;
- }
+void RasterizerCanvasGLES3::reset_canvas() {
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_DITHER);
+ glEnable(GL_BLEND);
- if (storage->frame.current_rt->copy_screen_effect.color) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
- }
+ // Default to Mix.
+ glBlendEquation(GL_FUNC_ADD);
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
+
+void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {
+}
+
+void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
+}
+
+void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
+}
+
+RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
+ // We interleave the vertex data into one big VBO to improve cache coherence
+ uint32_t vertex_count = p_points.size();
+ uint32_t stride = 2;
+ if ((uint32_t)p_colors.size() == vertex_count) {
+ stride += 4;
+ }
+ if ((uint32_t)p_uvs.size() == vertex_count) {
+ stride += 2;
+ }
+ if ((uint32_t)p_bones.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
+ stride += 4;
+ }
+
+ PolygonBuffers pb;
+ glGenBuffers(1, &pb.vertex_buffer);
+ glGenVertexArrays(1, &pb.vertex_array);
+ glBindVertexArray(pb.vertex_array);
+ pb.count = vertex_count;
+ pb.index_buffer = 0;
+
+ uint32_t buffer_size = stride * p_points.size();
+
+ Vector<uint8_t> polygon_buffer;
+ polygon_buffer.resize(buffer_size * sizeof(float));
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, pb.vertex_buffer);
+ glBufferData(GL_ARRAY_BUFFER, stride * vertex_count * sizeof(float), nullptr, GL_STATIC_DRAW); // TODO may not be necessary
+ const uint8_t *r = polygon_buffer.ptr();
+ float *fptr = (float *)r;
+ uint32_t *uptr = (uint32_t *)r;
+ uint32_t base_offset = 0;
+ {
+ // Always uses vertex positions
+ glEnableVertexAttribArray(RS::ARRAY_VERTEX);
+ glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL);
+ const Vector2 *points_ptr = p_points.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = points_ptr[i].x;
+ fptr[base_offset + i * stride + 1] = points_ptr[i].y;
}
- if (shader_ptr != r_ris.shader_cache) {
- if (shader_ptr->canvas_item.uses_time) {
- RenderingServerDefault::redraw_request();
- }
+ base_offset += 2;
+ }
- state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id);
- state.canvas_shader.bind();
+ // Next add colors
+ if (p_colors.size() == 1) {
+ glDisableVertexAttribArray(RS::ARRAY_COLOR);
+ Color m = p_colors[0];
+ glVertexAttrib4f(RS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
+ } else if ((uint32_t)p_colors.size() == vertex_count) {
+ glEnableVertexAttribArray(RS::ARRAY_COLOR);
+ glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
+
+ const Color *color_ptr = p_colors.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = color_ptr[i].r;
+ fptr[base_offset + i * stride + 1] = color_ptr[i].g;
+ fptr[base_offset + i * stride + 2] = color_ptr[i].b;
+ fptr[base_offset + i * stride + 3] = color_ptr[i].a;
}
+ base_offset += 4;
+ } else {
+ glDisableVertexAttribArray(RS::ARRAY_COLOR);
+ glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
+ }
- int tc = material_ptr->textures.size();
- Pair<StringName, RID> *textures = material_ptr->textures.ptrw();
-
- ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();
-
- for (int i = 0; i < tc; i++) {
- glActiveTexture(GL_TEXTURE0 + i);
-
- RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(textures[i].second);
-
- if (!t) {
- switch (texture_hints[i]) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
- } break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.aniso_tex);
- } break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
- } break;
- default: {
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
- } break;
- }
+ if ((uint32_t)p_uvs.size() == vertex_count) {
+ glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
+ glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
- continue;
- }
+ const Vector2 *uv_ptr = p_uvs.ptr();
- if (t->redraw_if_visible) {
- RenderingServerDefault::redraw_request();
- }
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ fptr[base_offset + i * stride + 0] = uv_ptr[i].x;
+ fptr[base_offset + i * stride + 1] = uv_ptr[i].y;
+ }
- t = t->get_ptr();
+ base_offset += 2;
+ } else {
+ glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
+ }
-#ifdef TOOLS_ENABLED
- if (t->detect_normal && texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) {
- t->detect_normal(t->detect_normal_ud);
- }
-#endif
- if (t->render_target)
- t->render_target->used_in_frame = true;
+ if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
+ glEnableVertexAttribArray(RS::ARRAY_BONES);
+ glVertexAttribPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
- glBindTexture(t->target, t->tex_id);
+ const int *bone_ptr = p_bones.ptr();
+
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
+
+ bone16w[0] = bone_ptr[i * 4 + 0];
+ bone16w[1] = bone_ptr[i * 4 + 1];
+ bone16w[2] = bone_ptr[i * 4 + 2];
+ bone16w[3] = bone_ptr[i * 4 + 3];
}
+ base_offset += 2;
} else {
- state.canvas_shader.set_custom_shader(0);
- state.canvas_shader.bind();
+ glDisableVertexAttribArray(RS::ARRAY_BONES);
}
- state.canvas_shader.use_material((void *)material_ptr);
- r_ris.shader_cache = shader_ptr;
+ if ((uint32_t)p_weights.size() == vertex_count * 4) {
+ glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);
+ glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
- r_ris.canvas_last_material = material;
+ const float *weight_ptr = p_weights.ptr();
- r_ris.rebind_shader = false;
- }
+ for (uint32_t i = 0; i < vertex_count; i++) {
+ uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride];
- int blend_mode = r_ris.shader_cache ? r_ris.shader_cache->canvas_item.blend_mode : RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX;
- bool unshaded = r_ris.shader_cache && (r_ris.shader_cache->canvas_item.light_mode == RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA));
- bool reclip = false;
+ weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
+ weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
+ weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
+ weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
+ }
- if (r_ris.last_blend_mode != blend_mode) {
- switch (blend_mode) {
- case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX: {
- glBlendEquation(GL_FUNC_ADD);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
- }
+ base_offset += 2;
+ } else {
+ glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);
+ }
- } break;
- case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_ADD: {
- glBlendEquation(GL_FUNC_ADD);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
- } else {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
- }
+ ERR_FAIL_COND_V(base_offset != stride, 0);
+ glBufferData(GL_ARRAY_BUFFER, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW);
+ }
- } break;
- case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_SUB: {
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
- } else {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
- }
- } break;
- case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MUL: {
- glBlendEquation(GL_FUNC_ADD);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);
- } else {
- glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE);
- }
- } break;
- case RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA: {
- glBlendEquation(GL_FUNC_ADD);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
- }
- } break;
+ if (p_indices.size()) {
+ //create indices, as indices were requested
+ Vector<uint8_t> index_buffer;
+ index_buffer.resize(p_indices.size() * sizeof(int32_t));
+ {
+ uint8_t *w = index_buffer.ptrw();
+ memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_indices.size());
}
+ glGenBuffers(1, &pb.index_buffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, nullptr, GL_STATIC_DRAW); // TODO may not be necessary
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_indices.size() * 4, index_buffer.ptr(), GL_STATIC_DRAW);
+ pb.count = p_indices.size();
}
- state.uniforms.final_modulate = unshaded ? p_ci->final_modulate : Color(p_ci->final_modulate.r * r_ris.item_group_modulate.r, p_ci->final_modulate.g * r_ris.item_group_modulate.g, p_ci->final_modulate.b * r_ris.item_group_modulate.b, p_ci->final_modulate.a * r_ris.item_group_modulate.a);
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- state.uniforms.modelview_matrix = p_ci->final_transform;
- state.uniforms.extra_matrix = Transform2D();
+ PolygonID id = polygon_buffers.last_id++;
- _set_uniforms();
+ polygon_buffers.polygons[id] = pb;
- if (unshaded || (state.uniforms.final_modulate.a > 0.001 && (!r_ris.shader_cache || r_ris.shader_cache->canvas_item.light_mode != RasterizerStorageGLES3::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !p_ci->light_masked))
- _legacy_canvas_item_render_commands(p_ci, NULL, reclip, material_ptr);
+ return id;
+}
+void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) {
+ PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
+ ERR_FAIL_COND(!pb_ptr);
- r_ris.rebind_shader = true; // hacked in for now.
+ PolygonBuffers &pb = *pb_ptr;
- if ((blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES3::Shader::CanvasItem::BLEND_MODE_PMALPHA) && r_ris.item_group_light && !unshaded) {
- Light *light = r_ris.item_group_light;
- bool light_used = false;
- RS::CanvasLightBlendMode bmode = RS::CANVAS_LIGHT_BLEND_MODE_ADD;
- state.uniforms.final_modulate = p_ci->final_modulate; // remove the canvas modulate
+ if (pb.index_buffer != 0) {
+ glDeleteBuffers(1, &pb.index_buffer);
+ }
- while (light) {
- if (p_ci->light_mask & light->item_mask && r_ris.item_group_z >= light->z_min && r_ris.item_group_z <= light->z_max && p_ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
- //intersects this light
+ glDeleteVertexArrays(1, &pb.vertex_array);
+ glDeleteBuffers(1, &pb.vertex_buffer);
- if (!light_used || bmode != light->blend_mode) {
- bmode = light->blend_mode;
+ polygon_buffers.polygons.erase(p_polygon);
+}
- switch (bmode) {
- case RS::CANVAS_LIGHT_BLEND_MODE_ADD: {
- glBlendEquation(GL_FUNC_ADD);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+// Creates a new uniform buffer and uses it right away
+// This expands the instance buffer continually
+// In theory allocations can reach as high as number_of_draw_calls * 3 frames
+// because OpenGL can start rendering subsequent frames before finishing the current one
+void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
+ GLuint new_buffer;
+ glGenBuffers(1, &new_buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, new_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * state.max_instances_per_batch, nullptr, GL_DYNAMIC_DRAW);
+ state.current_buffer = (state.current_buffer + 1);
+ state.canvas_instance_data_buffers.insert(state.current_buffer, new_buffer);
+ state.fences.insert(state.current_buffer, GLsync());
+ state.current_buffer = state.current_buffer % state.canvas_instance_data_buffers.size();
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+}
- } break;
- case RS::CANVAS_LIGHT_BLEND_MODE_SUB: {
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
- } break;
- case RS::CANVAS_LIGHT_BLEND_MODE_MIX: {
- // case RS::CANVAS_LIGHT_MODE_MASK: {
- glBlendEquation(GL_FUNC_ADD);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+void RasterizerCanvasGLES3::initialize() {
+ // quad buffer
+ {
+ glGenBuffers(1, &data.canvas_quad_vertices);
+ glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
- } break;
- }
- }
+ const float qv[8] = {
+ 0, 0,
+ 0, 1,
+ 1, 1,
+ 1, 0
+ };
- if (!light_used) {
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, true);
- light_used = true;
- }
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW);
- // FTODO
- //bool has_shadow = light->shadow_buffer.is_valid() && p_ci->light_mask & light->item_shadow_mask;
- bool has_shadow = light->use_shadow && p_ci->light_mask & light->item_shadow_mask;
-
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, has_shadow);
- if (has_shadow) {
- // FTODO
- //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_USE_GRADIENT, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_NONE);
- //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF3);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF5);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false);
- //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF7);
- //state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF9);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, light->shadow_filter == RS::CANVAS_LIGHT_FILTER_PCF13);
- }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- state.canvas_shader.bind();
- state.using_light = light;
- state.using_shadow = has_shadow;
+ glGenVertexArrays(1, &data.canvas_quad_array);
+ glBindVertexArray(data.canvas_quad_array);
+ glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
+ glEnableVertexAttribArray(0);
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ }
- //always re-set uniforms, since light parameters changed
- _set_uniforms();
- state.canvas_shader.use_material((void *)material_ptr);
+ {
+ //particle quad buffers
+
+ glGenBuffers(1, &data.particle_quad_vertices);
+ glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
+ {
+ //quad of size 1, with pivot on the center for particles, then regular UVS. Color is general plus fetched from particle
+ const float qv[16] = {
+ -0.5, -0.5,
+ 0.0, 0.0,
+ -0.5, 0.5,
+ 0.0, 1.0,
+ 0.5, 0.5,
+ 1.0, 1.0,
+ 0.5, -0.5,
+ 1.0, 0.0
+ };
+
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW);
+ }
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
- RasterizerStorageGLES3::Texture *t = storage->texture_owner.get_or_null(light->texture);
- if (!t) {
- glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
- } else {
- t = t->get_ptr();
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+
+ glGenVertexArrays(1, &data.particle_quad_array);
+ glBindVertexArray(data.particle_quad_array);
+ glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
+ glEnableVertexAttribArray(RS::ARRAY_VERTEX);
+ glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr);
+ glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
+ glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8));
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ }
- glBindTexture(t->target, t->tex_id);
- }
+ // ninepatch buffers
+ {
+ // array buffer
+ glGenBuffers(1, &data.ninepatch_vertices);
+ glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
- glActiveTexture(GL_TEXTURE0);
- _legacy_canvas_item_render_commands(p_ci, NULL, reclip, material_ptr); //redraw using light
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW);
- state.using_light = NULL;
- }
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
- light = light->next_ptr;
- }
+ // element buffer
+ glGenBuffers(1, &data.ninepatch_elements);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
- if (light_used) {
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_LIGHTING, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_SHADOWS, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_NEAREST, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF3, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF5, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF7, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF9, false);
- state.canvas_shader.set_conditional(CanvasShaderGLES3::SHADOW_FILTER_PCF13, false);
+#define _EIDX(y, x) (y * 4 + x)
+ uint8_t elems[3 * 2 * 9] = {
+ // first row
- state.canvas_shader.bind();
+ _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1),
+ _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0),
- r_ris.last_blend_mode = -1;
+ _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2),
+ _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1),
-#if 0
- //this is set again, so it should not be needed anyway?
- state.canvas_item_modulate = unshaded ? ci->final_modulate : Color(ci->final_modulate.r * p_modulate.r, ci->final_modulate.g * p_modulate.g, ci->final_modulate.b * p_modulate.b, ci->final_modulate.a * p_modulate.a);
+ _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3),
+ _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2),
- state.canvas_shader.set_uniform(CanvasShaderGLES3::MODELVIEW_MATRIX, state.final_transform);
- state.canvas_shader.set_uniform(CanvasShaderGLES3::EXTRA_MATRIX, Transform2D());
- state.canvas_shader.set_uniform(CanvasShaderGLES3::FINAL_MODULATE, state.canvas_item_modulate);
+ // second row
- glBlendEquation(GL_FUNC_ADD);
+ _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1),
+ _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0),
- if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
+ // the center one would be here, but we'll put it at the end
+ // so it's easier to disable the center and be able to use
+ // one draw call for both
- //@TODO RESET canvas_blend_mode
-#endif
- }
+ _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3),
+ _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2),
+
+ // third row
+
+ _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1),
+ _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0),
+
+ _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2),
+ _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1),
+
+ _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3),
+ _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2),
+
+ // center field
+
+ _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2),
+ _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1)
+ };
+#undef _EIDX
+
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
- if (reclip) {
- glEnable(GL_SCISSOR_TEST);
- int y = storage->frame.current_rt->height - (r_ris.current_clip->final_clip_rect.position.y + r_ris.current_clip->final_clip_rect.size.y);
- // FTODO
- // if (storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_VFLIP])
- // y = r_ris.current_clip->final_clip_rect.position.y;
- glScissor(r_ris.current_clip->final_clip_rect.position.x, y, r_ris.current_clip->final_clip_rect.size.width, r_ris.current_clip->final_clip_rect.size.height);
+ //state.canvas_shadow_shader.init();
+
+ int uniform_max_size;
+ glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &uniform_max_size);
+ if (uniform_max_size < 65536) {
+ state.max_lights_per_render = 64;
+ state.max_instances_per_batch = 128;
+ } else {
+ state.max_lights_per_render = 256;
+ state.max_instances_per_batch = 512;
}
-}
-void RasterizerCanvasGLES3::gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const {
- glEnable(GL_SCISSOR_TEST);
- glScissor(p_x, p_y, p_width, p_height);
-}
+ // Reserve 64 Uniform Buffers for instance data
+ state.canvas_instance_data_buffers.resize(64);
+ state.fences.resize(64);
+ glGenBuffers(64, state.canvas_instance_data_buffers.ptr());
+ for (int i = 0; i < 64; i++) {
+ glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_instance_data_buffers[i]);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(InstanceData) * state.max_instances_per_batch, nullptr, GL_DYNAMIC_DRAW);
+ }
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
-void RasterizerCanvasGLES3::gl_disable_scissor() const {
- glDisable(GL_SCISSOR_TEST);
-}
+ state.instance_data_array = memnew_arr(InstanceData, state.max_instances_per_batch);
-void RasterizerCanvasGLES3::initialize() {
- RasterizerCanvasBaseGLES3::initialize();
+ glGenBuffers(1, &state.canvas_state_buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_state_buffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
- batch_initialize();
+ String global_defines;
+ global_defines += "#define MAX_GLOBAL_VARIABLES 256\n"; // TODO: this is arbitrary for now
+ global_defines += "#define MAX_LIGHTS " + itos(state.max_instances_per_batch) + "\n";
+ global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(state.max_instances_per_batch) + "\n";
- // just reserve some space (may not be needed as we are orphaning, but hey ho)
- glGenBuffers(1, &bdata.gl_vertex_buffer);
+ state.canvas_shader.initialize(global_defines);
+ state.canvas_shader_default_version = state.canvas_shader.version_create();
+ state.canvas_shader.version_bind_shader(state.canvas_shader_default_version, CanvasShaderGLES3::MODE_QUAD);
- if (bdata.vertex_buffer_size_bytes) {
- glBindBuffer(GL_ARRAY_BUFFER, bdata.gl_vertex_buffer);
- glBufferData(GL_ARRAY_BUFFER, bdata.vertex_buffer_size_bytes, NULL, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
+ //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
- // pre fill index buffer, the indices never need to change so can be static
- glGenBuffers(1, &bdata.gl_index_buffer);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bdata.gl_index_buffer);
-
- Vector<uint16_t> indices;
- indices.resize(bdata.index_buffer_size_units);
-
- for (unsigned int q = 0; q < bdata.max_quads; q++) {
- int i_pos = q * 6; // 6 inds per quad
- int q_pos = q * 4; // 4 verts per quad
- indices.set(i_pos, q_pos);
- indices.set(i_pos + 1, q_pos + 1);
- indices.set(i_pos + 2, q_pos + 2);
- indices.set(i_pos + 3, q_pos);
- indices.set(i_pos + 4, q_pos + 2);
- indices.set(i_pos + 5, q_pos + 3);
-
- // we can only use 16 bit indices in OpenGL!
-#ifdef DEBUG_ENABLED
- CRASH_COND((q_pos + 3) > 65535);
-#endif
- }
+ //state.canvas_shader.bind();
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, bdata.index_buffer_size_bytes, &indices[0], GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ //state.lens_shader.init();
+
+ //state.canvas_shader.set_conditional(CanvasOldShaderGLES3::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
- } // only if there is a vertex buffer (batching is on)
+ {
+ default_canvas_group_shader = storage->shader_allocate();
+ storage->shader_initialize(default_canvas_group_shader);
+
+ storage->shader_set_code(default_canvas_group_shader, R"(
+// Default CanvasGroup shader.
+
+shader_type canvas_item;
+
+void fragment() {
+ vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
+
+ if (c.a > 0.0001) {
+ c.rgb /= c.a;
+ }
+
+ COLOR *= c;
+}
+)");
+ default_canvas_group_material = storage->material_allocate();
+ storage->material_initialize(default_canvas_group_material);
+
+ storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
+ }
+
+ default_canvas_texture = storage->canvas_texture_allocate();
+ storage->canvas_texture_initialize(default_canvas_texture);
+
+ state.using_light = NULL;
+ state.using_transparent_rt = false;
+ state.using_skeleton = false;
+ state.current_shader_version = state.canvas_shader_default_version;
}
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
- batch_constructor();
+}
+RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
+ state.canvas_shader.version_free(state.canvas_shader_default_version);
+ storage->free(default_canvas_group_material);
+ storage->free(default_canvas_group_shader);
+ storage->free(default_canvas_texture);
+}
+
+void RasterizerCanvasGLES3::finalize() {
+ glDeleteBuffers(1, &data.canvas_quad_vertices);
+ glDeleteVertexArrays(1, &data.canvas_quad_array);
+
+ glDeleteBuffers(1, &data.canvas_quad_vertices);
+ glDeleteVertexArrays(1, &data.canvas_quad_array);
}
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 5e85f84bde..908d79f9f8 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -31,41 +31,251 @@
#ifndef RASTERIZER_CANVAS_OPENGL_H
#define RASTERIZER_CANVAS_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
-#include "drivers/gles3/rasterizer_canvas_batcher.h"
-#include "rasterizer_canvas_base_gles3.h"
+#include "rasterizer_scene_gles3.h"
+#include "rasterizer_storage_gles3.h"
+#include "servers/rendering/renderer_canvas_render.h"
+#include "servers/rendering/renderer_compositor.h"
+
+#include "shaders/canvas.glsl.gen.h"
class RasterizerSceneGLES3;
-class RasterizerCanvasGLES3 : public RasterizerCanvasBaseGLES3, public RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3> {
- friend class RasterizerCanvasBatcher<RasterizerCanvasGLES3, RasterizerStorageGLES3>;
+class RasterizerCanvasGLES3 : public RendererCanvasRender {
+ _FORCE_INLINE_ void _update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4);
+ _FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
+
+ _FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4);
+ _FORCE_INLINE_ void _update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4);
+
+ enum {
+ BASE_UNIFORM_BUFFER_OBJECT = 0,
+ MATERIAL_UNIFORM_BUFFER_OBJECT = 1,
+ TRANSFORMS_UNIFORM_BUFFER_OBJECT = 2,
+ CANVAS_TEXTURE_UNIFORM_BUFFER_OBJECT = 3,
+ };
+
+ enum {
+
+ FLAGS_INSTANCING_MASK = 0x7F,
+ FLAGS_INSTANCING_HAS_COLORS = (1 << 7),
+ FLAGS_INSTANCING_HAS_CUSTOM_DATA = (1 << 8),
+
+ FLAGS_CLIP_RECT_UV = (1 << 9),
+ FLAGS_TRANSPOSE_RECT = (1 << 10),
-private:
- // legacy codepath .. to remove after testing
- void _legacy_canvas_render_item(Item *p_ci, RenderItemState &r_ris);
+ FLAGS_NINEPACH_DRAW_CENTER = (1 << 12),
+ FLAGS_USING_PARTICLES = (1 << 13),
- // high level batch funcs
- void canvas_render_items_implementation(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
- void render_batches(Item::Command *const *p_commands, Item *p_current_clip, bool &r_reclip, RasterizerStorageGLES3::Material *p_material);
+ FLAGS_USE_SKELETON = (1 << 15),
+ FLAGS_NINEPATCH_H_MODE_SHIFT = 16,
+ FLAGS_NINEPATCH_V_MODE_SHIFT = 18,
+ FLAGS_LIGHT_COUNT_SHIFT = 20,
- // funcs used from rasterizer_canvas_batcher template
- void gl_enable_scissor(int p_x, int p_y, int p_width, int p_height) const;
- void gl_disable_scissor() const;
+ FLAGS_DEFAULT_NORMAL_MAP_USED = (1 << 26),
+ FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27),
+
+ FLAGS_USE_MSDF = (1 << 28),
+ };
+
+ enum {
+ LIGHT_FLAGS_TEXTURE_MASK = 0xFFFF,
+ LIGHT_FLAGS_BLEND_SHIFT = 16,
+ LIGHT_FLAGS_BLEND_MASK = (3 << 16),
+ LIGHT_FLAGS_BLEND_MODE_ADD = (0 << 16),
+ LIGHT_FLAGS_BLEND_MODE_SUB = (1 << 16),
+ LIGHT_FLAGS_BLEND_MODE_MIX = (2 << 16),
+ LIGHT_FLAGS_BLEND_MODE_MASK = (3 << 16),
+ LIGHT_FLAGS_HAS_SHADOW = (1 << 20),
+ LIGHT_FLAGS_FILTER_SHIFT = 22
+
+ };
+
+ enum {
+ MAX_RENDER_ITEMS = 256 * 1024,
+ MAX_LIGHT_TEXTURES = 1024,
+ MAX_LIGHTS_PER_ITEM = 16,
+ DEFAULT_MAX_LIGHTS_PER_RENDER = 256,
+ };
public:
- void canvas_render_items_begin(const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
- void canvas_render_items_end();
- void canvas_render_items_internal(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform);
- void canvas_begin() override;
- void canvas_end() override;
+ struct StateBuffer {
+ float canvas_transform[16];
+ float screen_transform[16];
+ float canvas_normal_transform[16];
+ float canvas_modulate[4];
+
+ float screen_pixel_size[2];
+ float time;
+ uint32_t use_pixel_snap;
+
+ float sdf_to_tex[4];
+ float sdf_to_screen[2];
+ float screen_to_sdf[2];
+
+ uint32_t directional_light_count;
+ float tex_to_sdf;
+ uint32_t pad1;
+ uint32_t pad2;
+ };
+
+ struct InstanceData {
+ float world[6];
+ float color_texture_pixel_size[2];
+ union {
+ //rect
+ struct {
+ float modulation[4];
+ union {
+ float msdf[4];
+ float ninepatch_margins[4];
+ };
+ float dst_rect[4];
+ float src_rect[4];
+ float pad[2];
+ };
+ //primitive
+ struct {
+ float points[6]; // vec2 points[3]
+ float uvs[6]; // vec2 points[3]
+ uint32_t colors[6]; // colors encoded as half
+ };
+ };
+ uint32_t flags;
+ uint32_t specular_shininess;
+ uint32_t lights[4];
+ };
+
+ struct Data {
+ GLuint canvas_quad_vertices;
+ GLuint canvas_quad_array;
+
+ GLuint particle_quad_vertices;
+ GLuint particle_quad_array;
+
+ GLuint ninepatch_vertices;
+ GLuint ninepatch_elements;
+ } data;
+
+ struct State {
+ GLuint canvas_state_buffer;
+ LocalVector<GLuint> canvas_instance_data_buffers;
+ LocalVector<GLsync> fences;
+ uint32_t current_buffer = 0;
+
+ InstanceData *instance_data_array;
+ bool canvas_texscreen_used;
+ CanvasShaderGLES3 canvas_shader;
+ RID canvas_shader_current_version;
+ RID canvas_shader_default_version;
+ //CanvasShadowShaderGLES3 canvas_shadow_shader;
+ //LensDistortedShaderGLES3 lens_shader;
+
+ bool using_texture_rect;
+
+ bool using_ninepatch;
+ bool using_skeleton;
+
+ Transform2D skeleton_transform;
+ Transform2D skeleton_transform_inverse;
+ Size2i skeleton_texture_size;
+
+ RID current_tex = RID();
+ RID current_normal = RID();
+ RID current_specular = RID();
+ RasterizerStorageGLES3::Texture *current_tex_ptr;
+ RID current_shader_version = RID();
+ RS::PrimitiveType current_primitive = RS::PRIMITIVE_MAX;
+ uint32_t current_primitive_points = 0;
+ Item::Command::Type current_command = Item::Command::TYPE_RECT;
+
+ bool end_batch = false;
+
+ Transform3D vp;
+ Light *using_light;
+ bool using_shadow;
+ bool using_transparent_rt;
+
+ // FROM RD Renderer
+
+ uint32_t max_lights_per_render;
+ uint32_t max_lights_per_item;
+ uint32_t max_instances_per_batch;
+
+ RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+ RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+ } state;
+
+ Item *items[MAX_RENDER_ITEMS];
+
+ RID default_canvas_texture;
+ RID default_canvas_group_material;
+ RID default_canvas_group_shader;
+
+ typedef void Texture;
+
+ RasterizerSceneGLES3 *scene_render;
+
+ RasterizerStorageGLES3 *storage;
+
+ void _set_uniforms();
+
+ void canvas_begin();
+ void canvas_end();
+
+ //virtual void draw_window_margins(int *black_margin, RID *black_image) override;
+ void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample);
+
+ virtual void reset_canvas();
+ virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
+
+ virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override;
+
+ RID light_create() override;
+ void light_set_texture(RID p_rid, RID p_texture) override;
+ void light_set_use_shadow(RID p_rid, bool p_enable) override;
+ void light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) override;
+ void light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) override;
+
+ void render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) override;
+ RID occluder_polygon_create() override;
+ void occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) override;
+ void occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) override;
+ void set_shadow_texture_size(int p_size) override;
+
+ bool free(RID p_rid) override;
+ void update() override;
+
+ void _bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, RID &r_last_texture, Size2 &r_texpixel_size);
+
+ struct PolygonBuffers {
+ GLuint vertex_buffer;
+ GLuint vertex_array;
+ GLuint index_buffer;
+ int count;
+ };
+
+ struct {
+ HashMap<PolygonID, PolygonBuffers> polygons;
+ PolygonID last_id;
+ } polygon_buffers;
+
+ RendererCanvasRender::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;
+ void free_polygon(PolygonID p_polygon) override;
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override;
+ void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer = false);
+ void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index);
+ void _render_batch(uint32_t &p_max_index);
+ void _end_batch(uint32_t &p_max_index);
+ void _allocate_instance_data_buffer();
void initialize();
+ void finalize();
RasterizerCanvasGLES3();
+ ~RasterizerCanvasGLES3();
};
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
#endif // RASTERIZER_CANVAS_OPENGL_H
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 0840d03e44..32ead8aa7e 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -30,8 +30,7 @@
#include "rasterizer_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
-#include "shader_gles3.h"
+#ifdef GLES3_ENABLED
#include "core/config/project_settings.h"
#include "core/os/os.h"
@@ -91,21 +90,12 @@ void RasterizerGLES3::begin_frame(double frame_step) {
frame++;
delta = frame_step;
- // from 3.2
- time_total += frame_step * time_scale;
-
- if (frame_step == 0) {
- //to avoid hiccups
- frame_step = 0.001;
- }
+ time_total += frame_step;
double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
time_total = Math::fmod(time_total, time_roll_over);
- storage.frame.time[0] = time_total;
- storage.frame.time[1] = Math::fmod(time_total, 3600);
- storage.frame.time[2] = Math::fmod(time_total, 900);
- storage.frame.time[3] = Math::fmod(time_total, 60);
+ storage.frame.time = time_total;
storage.frame.count++;
storage.frame.delta = frame_step;
@@ -131,10 +121,11 @@ void RasterizerGLES3::end_frame(bool p_swap_buffers) {
// glClearColor(1, 0, 0, 1);
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- if (p_swap_buffers)
+ if (p_swap_buffers) {
DisplayServer::get_singleton()->swap_buffers();
- else
+ } else {
glFinish();
+ }
}
#ifdef CAN_DEBUG
@@ -272,32 +263,22 @@ RasterizerGLES3::RasterizerGLES3() {
void RasterizerGLES3::prepare_for_blitting_render_targets() {
}
-void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect) {
+void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) {
ERR_FAIL_COND(storage.frame.current_rt);
- // print_line("_blit_render_target_to_screen " + itos (p_screen) + ", rect " + String(Variant(p_screen_rect)));
-
RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
- canvas._set_texture_rect_mode(true);
- canvas.state.canvas_shader.set_custom_shader(0);
- canvas.state.canvas_shader.bind();
-
- canvas.canvas_begin();
+ // TODO: do we need a keep 3d linear option?
- glDisable(GL_BLEND);
- storage.bind_framebuffer_system();
- glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1);
if (rt->external.fbo != 0) {
- glBindTexture(GL_TEXTURE_2D, rt->external.color);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->external.fbo);
} else {
- glBindTexture(GL_TEXTURE_2D, rt->color);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
}
- canvas.draw_generic_textured_rect(p_screen_rect, Rect2(0, 0, 1, -1));
- glBindTexture(GL_TEXTURE_2D, 0);
-
- canvas.canvas_end();
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
// is this p_screen useless in a multi window environment?
@@ -313,7 +294,7 @@ void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_sc
RID rid_rt = blit.render_target;
Rect2 dst_rect = blit.dst_rect;
- _blit_render_target_to_screen(rid_rt, dst_rect);
+ _blit_render_target_to_screen(rid_rt, p_screen, dst_rect);
}
}
@@ -321,11 +302,10 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
if (p_image.is_null() || p_image->is_empty())
return;
- int window_w = 640; //OS::get_singleton()->get_video_mode(0).width;
- int window_h = 480; //OS::get_singleton()->get_video_mode(0).height;
+ Size2i win_size = DisplayServer::get_singleton()->screen_get_size();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glViewport(0, 0, window_w, window_h);
+ glViewport(0, 0, win_size.width, win_size.height);
glDisable(GL_BLEND);
glDepthMask(GL_FALSE);
if (false) {
@@ -346,27 +326,26 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
Rect2 screenrect;
if (p_scale) {
- if (window_w > window_h) {
+ if (win_size.width > win_size.height) {
//scale horizontally
- screenrect.size.y = window_h;
- screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y;
- screenrect.position.x = (window_w - screenrect.size.x) / 2;
+ screenrect.size.y = win_size.height;
+ screenrect.size.x = imgrect.size.x * win_size.height / imgrect.size.y;
+ screenrect.position.x = (win_size.width - screenrect.size.x) / 2;
} else {
//scale vertically
- screenrect.size.x = window_w;
- screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x;
- screenrect.position.y = (window_h - screenrect.size.y) / 2;
+ screenrect.size.x = win_size.width;
+ screenrect.size.y = imgrect.size.y * win_size.width / imgrect.size.x;
+ screenrect.position.y = (win_size.height - screenrect.size.y) / 2;
}
} else {
screenrect = imgrect;
- screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
+ screenrect.position += ((Size2(win_size.width, win_size.height) - screenrect.size) / 2.0).floor();
}
RasterizerStorageGLES3::Texture *t = storage.texture_owner.get_or_null(texture);
glActiveTexture(GL_TEXTURE0 + storage.config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, t->tex_id);
- canvas.draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
glBindTexture(GL_TEXTURE_2D, 0);
canvas.canvas_end();
@@ -375,4 +354,4 @@ void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_c
end_frame(true);
}
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index e2f3e0bdd0..a641e189c5 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -31,8 +31,7 @@
#ifndef RASTERIZER_OPENGL_H
#define RASTERIZER_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
@@ -45,14 +44,13 @@ private:
float delta = 0;
double time_total = 0.0;
- double time_scale = 1.0;
protected:
- RasterizerCanvasGLES3 canvas;
RasterizerStorageGLES3 storage;
+ RasterizerCanvasGLES3 canvas;
RasterizerSceneGLES3 scene;
- void _blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect);
+ void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect);
public:
RendererStorage *get_storage() { return &storage; }
@@ -87,6 +85,6 @@ public:
~RasterizerGLES3() {}
};
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
#endif
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 77e0366f0e..9e7d4f5435 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "rasterizer_scene_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
// TODO: 3D support not implemented yet.
@@ -471,4 +471,4 @@ void RasterizerSceneGLES3::light_projectors_set_filter(RS::LightProjectorFilter
RasterizerSceneGLES3::RasterizerSceneGLES3() {
}
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 9b356f28df..b73c053bc7 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -31,8 +31,7 @@
#ifndef RASTERIZER_SCENE_OPENGL_H
#define RASTERIZER_SCENE_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "core/math/camera_matrix.h"
#include "core/templates/rid_owner.h"
@@ -41,12 +40,11 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
-#include "shaders/scene.glsl.gen.h"
class RasterizerSceneGLES3 : public RendererSceneRender {
public:
struct State {
- SceneShaderGLES3 scene_shader;
+ //SceneShaderGLES3 scene_shader;
} state;
GeometryInstance *geometry_instance_create(RID p_base) override;
@@ -227,6 +225,6 @@ public:
RasterizerSceneGLES3();
};
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
#endif // RASTERIZER_SCENE_OPENGL_H
diff --git a/drivers/gles3/rasterizer_storage_common.h b/drivers/gles3/rasterizer_storage_common.h
deleted file mode 100644
index d9a756af1f..0000000000
--- a/drivers/gles3/rasterizer_storage_common.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*************************************************************************/
-/* rasterizer_storage_common.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 RASTERIZER_STORAGE_COMMON_H
-#define RASTERIZER_STORAGE_COMMON_H
-
-class RasterizerStorageCommon {
-public:
- enum FVF {
- FVF_UNBATCHED,
- FVF_REGULAR,
- FVF_COLOR,
- FVF_LIGHT_ANGLE,
- FVF_MODULATED,
- FVF_LARGE,
- };
-
- // these flags are specifically for batching
- // some of the logic is thus in rasterizer_storage.cpp
- // we could alternatively set bitflags for each 'uses' and test on the fly
- enum BatchFlags {
- PREVENT_COLOR_BAKING = 1 << 0,
- PREVENT_VERTEX_BAKING = 1 << 1,
-
- // custom vertex shaders using BUILTINS that vary per item
- PREVENT_ITEM_JOINING = 1 << 2,
-
- USE_MODULATE_FVF = 1 << 3,
- USE_LARGE_FVF = 1 << 4,
- };
-
- enum BatchType : uint16_t {
- BT_DEFAULT = 0,
- BT_RECT = 1,
- BT_LINE = 2,
- BT_LINE_AA = 3,
- BT_POLY = 4,
- BT_DUMMY = 5, // dummy batch is just used to keep the batch creation loop simple
- };
-
- enum BatchTypeFlags {
- BTF_DEFAULT = 1 << BT_DEFAULT,
- BTF_RECT = 1 << BT_RECT,
- BTF_LINE = 1 << BT_LINE,
- BTF_LINE_AA = 1 << BT_LINE_AA,
- BTF_POLY = 1 << BT_POLY,
- };
-};
-
-#endif // RASTERIZER_STORAGE_COMMON_H
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index e010e55307..db449b7a08 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -28,14 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-//#define OPENGL_DISABLE_RENDER_TARGETS
-
#include "rasterizer_storage_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "core/config/project_settings.h"
#include "core/math/transform_3d.h"
-#include "drivers/gles3/rasterizer_storage_common.h"
#include "rasterizer_canvas_gles3.h"
#include "rasterizer_scene_gles3.h"
#include "servers/rendering/shader_language.h"
@@ -1061,12 +1058,12 @@ void RasterizerStorageGLES3::_texture_set_state_from_flags(Texture *p_tex) {
if (((p_tex->flags & TEXTURE_FLAG_REPEAT) || (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT)) && p_tex->target != GL_TEXTURE_CUBE_MAP) {
if (p_tex->flags & TEXTURE_FLAG_MIRRORED_REPEAT) {
- p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
+ p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
} else {
- p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+ p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
}
} else {
- p_tex->GLSetRepeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+ p_tex->GLSetRepeat(p_tex->target, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
}
}
@@ -1285,21 +1282,43 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
}
RID RasterizerStorageGLES3::canvas_texture_allocate() {
- return RID();
+ return canvas_texture_owner.allocate_rid();
}
void RasterizerStorageGLES3::canvas_texture_initialize(RID p_rid) {
+ canvas_texture_owner.initialize_rid(p_rid);
}
void RasterizerStorageGLES3::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
+ CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+ switch (p_channel) {
+ case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
+ ct->diffuse = p_texture;
+ } break;
+ case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
+ ct->normal_map = p_texture;
+ } break;
+ case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
+ ct->specular = p_texture;
+ } break;
+ }
}
-void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
+void RasterizerStorageGLES3::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
+ CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+ ct->specular_color.r = p_specular_color.r;
+ ct->specular_color.g = p_specular_color.g;
+ ct->specular_color.b = p_specular_color.b;
+ ct->specular_color.a = p_shininess;
}
-void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
+void RasterizerStorageGLES3::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
+ CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+ ct->texture_filter = p_filter;
}
-void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
+void RasterizerStorageGLES3::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
+ CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
+ ct->texture_repeat = p_repeat;
}
RID RasterizerStorageGLES3::sky_create() {
@@ -1309,169 +1328,14 @@ RID RasterizerStorageGLES3::sky_create() {
}
void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
- Sky *sky = sky_owner.get_or_null(p_sky);
- ERR_FAIL_COND(!sky);
-
- if (sky->panorama.is_valid()) {
- sky->panorama = RID();
- glDeleteTextures(1, &sky->radiance);
- sky->radiance = 0;
- }
-
- sky->panorama = p_panorama;
- if (!sky->panorama.is_valid()) {
- return; // the panorama was cleared
- }
-
- Texture *texture = texture_owner.get_or_null(sky->panorama);
- if (!texture) {
- sky->panorama = RID();
- ERR_FAIL_COND(!texture);
- }
-
- // glBindVertexArray(0) and more
- {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_BLEND);
-
- for (int i = 0; i < RS::ARRAY_MAX - 1; i++) {
- //glDisableVertexAttribArray(i);
- }
- }
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(texture->target, texture->tex_id);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, resources.radical_inverse_vdc_cache_tex);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- // New cubemap that will hold the mipmaps with different roughness values
- glActiveTexture(GL_TEXTURE2);
- glGenTextures(1, &sky->radiance);
- glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
-
- int size = p_radiance_size / 2; //divide by two because its a cubemap (this is an approximation because GLES3 uses a dual paraboloid)
-
- GLenum internal_format = GL_RGB;
- GLenum format = GL_RGB;
- GLenum type = GL_UNSIGNED_BYTE;
-
- // Set the initial (empty) mipmaps
- // Mobile hardware (PowerVR specially) prefers this approach,
- // the previous approach with manual lod levels kills the game.
- for (int i = 0; i < 6; i++) {
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
- }
-
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
-
- // No filters for now
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- // Framebuffer
-
- bind_framebuffer(resources.mipmap_blur_fbo);
-
- int mipmaps = 6;
- int lod = 0;
- int mm_level = mipmaps;
- size = p_radiance_size / 2;
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true);
- shaders.cubemap_filter.bind();
-
- // third, render to the framebuffer using separate textures, then copy to mipmaps
- while (size >= 1) {
- //make framebuffer size the texture size, need to use a separate texture for compatibility
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resources.mipmap_blur_color, 0);
-
- if (lod == 1) {
- //bind panorama for smaller lods
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_CUBE_MAP, sky->radiance);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
- shaders.cubemap_filter.bind();
- }
- glViewport(0, 0, size, size);
- bind_quad_array();
-
- glActiveTexture(GL_TEXTURE2); //back to panorama
-
- for (int i = 0; i < 6; i++) {
- shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::FACE_ID, i);
-
- float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1;
- roughness = MIN(1.0, roughness); //keep max at 1
- shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, roughness);
- shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, false);
-
- //glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glCopyTexSubImage2D(_cube_side_enum[i], lod, 0, 0, 0, 0, size, size);
- }
-
- size >>= 1;
-
- mm_level--;
-
- lod++;
- }
-
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
-
- // restore ranges
- glActiveTexture(GL_TEXTURE2); //back to panorama
-
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glActiveTexture(GL_TEXTURE3); //back to panorama
- glBindTexture(GL_TEXTURE_2D, 0);
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, 0);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, 0);
-
- //reset flags on Sky Texture that may have changed
- texture_set_flags(sky->panorama, texture->flags);
-
- // Framebuffer did its job. thank mr framebuffer
- glActiveTexture(GL_TEXTURE0); //back to panorama
- bind_framebuffer_system();
}
/* SHADER API */
RID RasterizerStorageGLES3::shader_allocate() {
Shader *shader = memnew(Shader);
- shader->mode = RS::SHADER_SPATIAL;
- shader->shader = &scene->state.scene_shader;
+ shader->mode = RS::SHADER_CANVAS_ITEM;
+ //shader->shader = &scene->state.scene_shader;
RID rid = shader_owner.make_rid(shader);
_shader_make_dirty(shader);
shader->self = rid;
@@ -1510,16 +1374,22 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code)
String mode_string = ShaderLanguage::get_shader_type(p_code);
RS::ShaderMode mode;
- if (mode_string == "canvas_item")
+ if (mode_string == "canvas_item") {
mode = RS::SHADER_CANVAS_ITEM;
- else if (mode_string == "particles")
+ } else if (mode_string == "particles") {
mode = RS::SHADER_PARTICLES;
- else
+ } else if (mode_string == "sky") {
+ mode = RS::SHADER_SKY;
+ } else if (mode_string == "spatial") {
mode = RS::SHADER_SPATIAL;
+ } else {
+ mode = RS::SHADER_MAX;
+ ERR_PRINT("shader type " + mode_string + " not supported in OpenGL renderer");
+ }
- if (shader->custom_code_id && mode != shader->mode) {
- shader->shader->free_custom_shader(shader->custom_code_id);
- shader->custom_code_id = 0;
+ if (shader->version.is_valid() && mode != shader->mode) {
+ shader->shader->version_free(shader->version);
+ shader->version = RID();
}
shader->mode = mode;
@@ -1529,13 +1399,15 @@ void RasterizerStorageGLES3::shader_set_code(RID p_shader, const String &p_code)
shader->shader = &canvas->state.canvas_shader;
} else if (mode == RS::SHADER_SPATIAL) {
- shader->shader = &scene->state.scene_shader;
+ //shader->shader = &scene->state.scene_shader;
+ } else if (mode == RS::SHADER_PARTICLES) {
+ } else if (mode == RS::SHADER_SKY) {
} else {
return;
}
- if (shader->custom_code_id == 0) {
- shader->custom_code_id = shader->shader->create_custom_shader();
+ if (shader->version.is_null() && shader->shader) {
+ shader->version = shader->shader->version_create();
}
_shader_make_dirty(shader);
@@ -1559,8 +1431,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
return; //just invalid, but no error
}
- ShaderCompilerGLES3::GeneratedCode gen_code;
- ShaderCompilerGLES3::IdentifierActions *actions = NULL;
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions *actions = NULL;
switch (p_shader->mode) {
case RS::SHADER_CANVAS_ITEM: {
@@ -1573,7 +1445,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->canvas_item.uses_modulate = false;
p_shader->canvas_item.uses_color = false;
p_shader->canvas_item.uses_vertex = false;
- p_shader->canvas_item.batch_flags = 0;
p_shader->canvas_item.uses_world_matrix = false;
p_shader->canvas_item.uses_extra_matrix = false;
@@ -1608,6 +1479,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
} break;
case RS::SHADER_SPATIAL: {
+ // TODO remove once 3D is added back
+ return;
p_shader->spatial.blend_mode = Shader::Spatial::BLEND_MODE_MIX;
p_shader->spatial.depth_draw_mode = Shader::Spatial::DEPTH_DRAW_OPAQUE;
p_shader->spatial.cull_mode = Shader::Spatial::CULL_MODE_BACK;
@@ -1670,14 +1543,6 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
-
- if (p_shader->spatial.uses_screen_texture && p_shader->spatial.uses_depth_texture) {
- ERR_PRINT_ONCE("Using both SCREEN_TEXTURE and DEPTH_TEXTURE is not supported in OpenGL");
- }
-
- if (p_shader->spatial.uses_depth_texture && !config.support_depth_texture) {
- ERR_PRINT_ONCE("Using DEPTH_TEXTURE is not permitted on this hardware, operation will fail.");
- }
} break;
default: {
@@ -1690,38 +1555,23 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
return;
}
- p_shader->shader->set_custom_shader_code(p_shader->custom_code_id, gen_code.vertex, gen_code.vertex_global, gen_code.fragment, gen_code.light, gen_code.fragment_global, gen_code.uniforms, gen_code.texture_uniforms, gen_code.custom_defines);
+ Vector<StringName> texture_uniform_names;
+ for (int i = 0; i < gen_code.texture_uniforms.size(); i++) {
+ texture_uniform_names.push_back(gen_code.texture_uniforms[i].name);
+ }
+
+ p_shader->shader->version_set_code(p_shader->version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines, texture_uniform_names);
- p_shader->texture_count = gen_code.texture_uniforms.size();
- p_shader->texture_hints = gen_code.texture_hints;
+ p_shader->texture_uniforms = gen_code.texture_uniforms;
p_shader->uses_vertex_time = gen_code.uses_vertex_time;
p_shader->uses_fragment_time = gen_code.uses_fragment_time;
- // some logic for batching
- if (p_shader->mode == RS::SHADER_CANVAS_ITEM) {
- if (p_shader->canvas_item.uses_modulate | p_shader->canvas_item.uses_color) {
- p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_COLOR_BAKING;
- }
- if (p_shader->canvas_item.uses_vertex) {
- p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_VERTEX_BAKING;
- }
- if (p_shader->canvas_item.uses_world_matrix | p_shader->canvas_item.uses_extra_matrix | p_shader->canvas_item.uses_projection_matrix | p_shader->canvas_item.uses_instance_custom) {
- p_shader->canvas_item.batch_flags |= RasterizerStorageCommon::PREVENT_ITEM_JOINING;
- }
- }
-
- p_shader->shader->set_custom_shader(p_shader->custom_code_id);
- p_shader->shader->bind();
-
- // cache uniform locations
-
for (SelfList<Material> *E = p_shader->materials.first(); E; E = E->next()) {
_material_make_dirty(E->self());
}
p_shader->valid = true;
- p_shader->version++;
}
void RasterizerStorageGLES3::update_dirty_shaders() {
@@ -1905,31 +1755,6 @@ RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const
return RID();
}
-void RasterizerStorageGLES3::shader_add_custom_define(RID p_shader, const String &p_define) {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
-
- shader->shader->add_custom_define(p_define);
-
- _shader_make_dirty(shader);
-}
-
-void RasterizerStorageGLES3::shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
-
- shader->shader->get_custom_defines(p_defines);
-}
-
-void RasterizerStorageGLES3::shader_remove_custom_define(RID p_shader, const String &p_define) {
- Shader *shader = shader_owner.get_or_null(p_shader);
- ERR_FAIL_COND(!shader);
-
- shader->shader->remove_custom_define(p_define);
-
- _shader_make_dirty(shader);
-}
-
/* COMMON MATERIAL API */
void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
@@ -2186,8 +2011,8 @@ void RasterizerStorageGLES3::_update_material(Material *p_material) {
// uniforms and other things will be set in the use_material method in ShaderGLES3
- if (p_material->shader && p_material->shader->texture_count > 0) {
- p_material->textures.resize(p_material->shader->texture_count);
+ if (p_material->shader && p_material->shader->texture_uniforms.size() > 0) {
+ p_material->textures.resize(p_material->shader->texture_uniforms.size());
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
if (E->get().texture_order < 0)
@@ -2325,7 +2150,7 @@ RS::SurfaceData RasterizerStorageGLES3::mesh_get_surface(RID p_mesh, int p_surfa
}
int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const {
- return 0;
+ return 1;
}
void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
@@ -3125,39 +2950,20 @@ bool RasterizerStorageGLES3::particles_is_inactive(RID p_particles) const {
/* RENDER TARGET */
void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- // FTODO
- // if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
- // // pending clear request. Do that first.
- // glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
- // glClearColor(storage->frame.clear_request_color.r,
- // storage->frame.clear_request_color.g,
- // storage->frame.clear_request_color.b,
- // storage->frame.clear_request_color.a);
- // glClear(GL_COLOR_BUFFER_BIT);
- // }
-
if (rt) {
if (rt->allocate_is_dirty) {
rt->allocate_is_dirty = false;
_render_target_allocate(rt);
}
- // if (p_render_target.is_valid()) {
- // RasterizerStorageGLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target);
frame.current_rt = rt;
ERR_FAIL_COND(!rt);
frame.clear_request = false;
glViewport(0, 0, rt->width, rt->height);
- // print_line("_set_current_render_target w " + itos(rt->width) + " h " + itos(rt->height));
-
_dims.rt_width = rt->width;
_dims.rt_height = rt->height;
_dims.win_width = rt->width;
@@ -3166,17 +2972,11 @@ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
} else {
frame.current_rt = NULL;
frame.clear_request = false;
- // FTODO
- // glViewport(0, 0, OS::get_singleton()->get_window_size().width, OS::get_singleton()->get_window_size().height);
bind_framebuffer_system();
}
}
void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
// do not allocate a render target with no size
if (rt->width <= 0 || rt->height <= 0)
return;
@@ -3515,10 +3315,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
}
void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
// there is nothing to clear when DIRECT_TO_SCREEN is used
if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN])
return;
@@ -3599,10 +3395,6 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
}
RID RasterizerStorageGLES3::render_target_create() {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
-// return RID();
-#endif
-
RenderTarget *rt = memnew(RenderTarget);
Texture *t = memnew(Texture);
@@ -3631,10 +3423,6 @@ RID RasterizerStorageGLES3::render_target_create() {
}
void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3643,10 +3431,6 @@ void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int
}
void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3664,11 +3448,15 @@ void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_w
//_render_target_allocate(rt);
}
-RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return RID();
-#endif
+// TODO: convert to Size2i internally
+Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
+ ERR_FAIL_COND_V(!rt, Size2());
+
+ return Size2i(rt->width, rt->height);
+}
+RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -3680,10 +3468,6 @@ RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3789,10 +3573,6 @@ void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_tar
}
void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3825,10 +3605,6 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
}
bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return false;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
@@ -3836,10 +3612,6 @@ bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3847,10 +3619,6 @@ void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
}
void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3868,10 +3636,6 @@ void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::Vie
//}
void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3879,10 +3643,6 @@ void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, boo
}
void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
@@ -3894,10 +3654,6 @@ void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target
}
void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = true;
@@ -3909,55 +3665,23 @@ void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, co
}
bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return false;
-#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->clear_requested;
}
Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return Color();
-#endif
-
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, Color());
return rt->clear_color;
}
void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = false;
}
void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) {
-#ifdef OPENGL_DISABLE_RENDER_TARGETS
- return;
-#endif
-
- // NEW for GLES...
- // This is being called at the wrong time. Instead it will be performed
- // at canvas begin
- return;
-
- /*
- RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
- ERR_FAIL_COND(!rt);
- if (!rt->clear_requested) {
- return;
- }
-
- const Color &c = rt->clear_color;
-
- glClearColor(c.r, c.g, c.b, c.a);
- // more bits?
- glClear(GL_COLOR_BUFFER_BIT);
- */
}
void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
@@ -4160,12 +3884,18 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
Texture *t = texture_owner.get_or_null(p_rid);
// can't free a render target texture
ERR_FAIL_COND_V(t->render_target, true);
+ if (t->canvas_texture) {
+ memdelete(t->canvas_texture);
+ }
info.texture_mem -= t->total_data_size;
texture_owner.free(p_rid);
memdelete(t);
return true;
+ } else if (canvas_texture_owner.owns(p_rid)) {
+ canvas_texture_owner.free(p_rid);
+ return true;
} else if (sky_owner.owns(p_rid)) {
Sky *sky = sky_owner.get_or_null(p_rid);
sky_set_texture(p_rid, RID(), 256);
@@ -4176,8 +3906,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.get_or_null(p_rid);
- if (shader->shader && shader->custom_code_id) {
- shader->shader->free_custom_shader(shader->custom_code_id);
+ if (shader->shader && shader->version.is_valid()) {
+ shader->shader->version_free(shader->version);
}
if (shader->dirty_list.in_list()) {
@@ -4482,7 +4212,6 @@ void RasterizerStorageGLES3::initialize() {
}
}
- // FTODO
config.keep_original_textures = true; // false
config.shrink_textures_x2 = false;
config.depth_internalformat = GL_DEPTH_COMPONENT;
@@ -4654,10 +4383,12 @@ void RasterizerStorageGLES3::initialize() {
// OR max_vertex_texture_image_units is zero
config.use_skeleton_software = (config.float_texture_supported == false) || (config.max_vertex_texture_image_units == 0);
- shaders.copy.init();
- shaders.cubemap_filter.init();
- bool ggx_hq = false; //GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
+ shaders.copy.initialize();
+ shaders.copy_version = shaders.copy.version_create(); //TODO
+ shaders.copy.version_bind_shader(shaders.copy_version, CopyShaderGLES3::MODE_COPY_SECTION);
+ //shaders.cubemap_filter.init();
+ //bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
+ //shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
{
// quad for copying stuff
@@ -4831,4 +4562,8 @@ RasterizerStorageGLES3::RasterizerStorageGLES3() {
config.should_orphan = true;
}
-#endif // GLES3_BACKEND_ENABLED
+RasterizerStorageGLES3::~RasterizerStorageGLES3() {
+ shaders.copy.version_free(shaders.copy_version);
+}
+
+#endif // GLES3_ENABLED
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 807789586b..c080d28f94 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -31,21 +31,17 @@
#ifndef RASTERIZER_STORAGE_OPENGL_H
#define RASTERIZER_STORAGE_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
-#include "drivers/gles3/rasterizer_asserts.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
-#include "shader_compiler_gles3.h"
-#include "shader_gles3.h"
#include "shaders/copy.glsl.gen.h"
-#include "shaders/cubemap_filter.glsl.gen.h"
class RasterizerCanvasGLES3;
class RasterizerSceneGLES3;
@@ -134,14 +130,15 @@ public:
} resources;
mutable struct Shaders {
- ShaderCompilerGLES3 compiler;
+ ShaderCompiler compiler;
CopyShaderGLES3 copy;
- CubemapFilterShaderGLES3 cubemap_filter;
+ RID copy_version;
+ //CubemapFilterShaderGLES3 cubemap_filter;
- ShaderCompilerGLES3::IdentifierActions actions_canvas;
- ShaderCompilerGLES3::IdentifierActions actions_scene;
- ShaderCompilerGLES3::IdentifierActions actions_particles;
+ ShaderCompiler::IdentifierActions actions_canvas;
+ ShaderCompiler::IdentifierActions actions_scene;
+ ShaderCompiler::IdentifierActions actions_particles;
} shaders;
@@ -183,62 +180,6 @@ public:
void bind_quad_array() const;
/////////////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////DATA///////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////
-
- /*
- struct Instantiable {
- RID self;
-
- SelfList<InstanceBaseDependency>::List instance_list;
-
- _FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) {
- SelfList<InstanceBaseDependency> *instances = instance_list.first();
- while (instances) {
- instances->self()->base_changed(p_aabb, p_materials);
- instances = instances->next();
- }
- }
-
- _FORCE_INLINE_ void instance_remove_deps() {
- SelfList<InstanceBaseDependency> *instances = instance_list.first();
-
- while (instances) {
- instances->self()->base_removed();
- instances = instances->next();
- }
- }
-
- Instantiable() {}
-
- ~Instantiable() {}
- };
-
- struct GeometryOwner : public Instantiable {
- };
-
- struct Geometry : public Instantiable {
- enum Type {
- GEOMETRY_INVALID,
- GEOMETRY_SURFACE,
- GEOMETRY_IMMEDIATE,
- GEOMETRY_MULTISURFACE
- };
-
- Type type;
- RID material;
- uint64_t last_pass;
- uint32_t index;
-
- void material_changed_notify() {}
-
- Geometry() {
- last_pass = 0;
- index = 0;
- }
- };
-*/
- /////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////API////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
@@ -257,6 +198,26 @@ public:
TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER
};
+ /* CANVAS TEXTURE API (2D) */
+
+ struct CanvasTexture {
+ RID diffuse;
+ RID normal_map;
+ RID specular;
+ Color specular_color = Color(1, 1, 1, 1);
+ float shininess = 1.0;
+
+ RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT;
+ RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT;
+
+ Size2i size_cache = Size2i(1, 1);
+ bool use_normal_cache = false;
+ bool use_specular_cache = false;
+ bool cleared_cache = true;
+ };
+
+ RID_Owner<CanvasTexture, true> canvas_texture_owner;
+
struct RenderTarget;
struct Texture {
@@ -309,6 +270,8 @@ public:
RS::TextureDetectCallback detect_normal;
void *detect_normal_ud;
+ CanvasTexture *canvas_texture = nullptr;
+
// some silly opengl shenanigans where
// texture coords start from bottom left, means we need to draw render target textures upside down
// to be compatible with vulkan etc.
@@ -436,7 +399,7 @@ public:
glTexParameteri(p_target, GL_TEXTURE_MIN_FILTER, pmin);
glTexParameteri(p_target, GL_TEXTURE_MAG_FILTER, pmag);
}
- void GLSetRepeat(RS::CanvasItemTextureRepeat p_repeat) {
+ void GLSetRepeat(GLenum p_target, RS::CanvasItemTextureRepeat p_repeat) {
if (p_repeat == state_repeat)
return;
state_repeat = p_repeat;
@@ -451,8 +414,8 @@ public:
prep = GL_MIRRORED_REPEAT;
} break;
}
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, prep);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, prep);
+ glTexParameteri(p_target, GL_TEXTURE_WRAP_S, prep);
+ glTexParameteri(p_target, GL_TEXTURE_WRAP_T, prep);
}
private:
@@ -540,10 +503,10 @@ public:
void canvas_texture_initialize(RID p_rid) override;
void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override;
- void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override;
+ void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) override;
- void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override;
- void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override;
+ void canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) override;
+ void canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) override;
/* SKY API */
// not sure if used in godot 4?
@@ -573,16 +536,13 @@ public:
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- uint32_t texture_count;
-
- uint32_t custom_code_id;
- uint32_t version;
+ RID version;
SelfList<Shader> dirty_list;
Map<StringName, Map<int, RID>> default_textures;
- Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
bool valid;
@@ -610,12 +570,6 @@ public:
int light_mode;
- // these flags are specifically for batching
- // some of the logic is thus in rasterizer_storage.cpp
- // we could alternatively set bitflags for each 'uses' and test on the fly
- // defined in RasterizerStorageCommon::BatchFlags
- unsigned int batch_flags;
-
bool uses_screen_texture;
bool uses_screen_uv;
bool uses_time;
@@ -686,8 +640,7 @@ public:
dirty_list(this) {
shader = NULL;
valid = false;
- custom_code_id = 0;
- version = 1;
+ version = RID();
last_pass = 0;
}
};
@@ -711,10 +664,6 @@ public:
RS::ShaderNativeSourceCode shader_get_native_source_code(RID p_shader) const override { return RS::ShaderNativeSourceCode(); };
- void shader_add_custom_define(RID p_shader, const String &p_define);
- void shader_get_custom_defines(RID p_shader, Vector<String> *p_defines) const;
- void shader_remove_custom_define(RID p_shader, const String &p_define);
-
void _update_shader(Shader *p_shader) const;
void update_dirty_shaders();
@@ -838,6 +787,44 @@ public:
/* MULTIMESH API */
+ struct MultiMesh {
+ RID mesh;
+ int instances = 0;
+ RS::MultimeshTransformFormat xform_format = RS::MULTIMESH_TRANSFORM_3D;
+ bool uses_colors = false;
+ bool uses_custom_data = false;
+ int visible_instances = -1;
+ AABB aabb;
+ bool aabb_dirty = false;
+ bool buffer_set = false;
+ uint32_t stride_cache = 0;
+ uint32_t color_offset_cache = 0;
+ uint32_t custom_data_offset_cache = 0;
+
+ Vector<float> data_cache; //used if individual setting is used
+ bool *data_cache_dirty_regions = nullptr;
+ uint32_t data_cache_used_dirty_regions = 0;
+
+ RID buffer; //storage buffer
+ RID uniform_set_3d;
+ RID uniform_set_2d;
+
+ bool dirty = false;
+ MultiMesh *dirty_list = nullptr;
+
+ Dependency dependency;
+ };
+
+ mutable RID_Owner<MultiMesh, true> multimesh_owner;
+
+ MultiMesh *multimesh_dirty_list = nullptr;
+
+ _FORCE_INLINE_ void _multimesh_make_local(MultiMesh *multimesh) const;
+ _FORCE_INLINE_ void _multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_mark_all_dirty(MultiMesh *multimesh, bool p_data, bool p_aabb);
+ _FORCE_INLINE_ void _multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances);
+ void _update_dirty_multimeshes();
+
RID multimesh_allocate() override;
void multimesh_initialize(RID p_rid) override;
void multimesh_allocate_data(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors = false, bool p_use_custom_data = false) override;
@@ -862,6 +849,29 @@ public:
void multimesh_set_visible_instances(RID p_multimesh, int p_visible) override;
int multimesh_get_visible_instances(RID p_multimesh) const override;
+ _FORCE_INLINE_ RS::MultimeshTransformFormat multimesh_get_transform_format(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->xform_format;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_colors(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->uses_colors;
+ }
+
+ _FORCE_INLINE_ bool multimesh_uses_custom_data(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ return multimesh->uses_custom_data;
+ }
+
+ _FORCE_INLINE_ uint32_t multimesh_get_instances_to_draw(RID p_multimesh) const {
+ MultiMesh *multimesh = multimesh_owner.get_or_null(p_multimesh);
+ if (multimesh->visible_instances >= 0) {
+ return multimesh->visible_instances;
+ }
+ return multimesh->instances;
+ }
+
/* SKELETON API */
RID skeleton_allocate() override;
@@ -1258,6 +1268,7 @@ public:
RID render_target_create() override;
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, uint32_t p_view_count) override;
+ Size2i render_target_get_size(RID p_render_target);
RID render_target_get_texture(RID p_render_target) override;
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
@@ -1330,7 +1341,7 @@ public:
bool clear_request;
Color clear_request_color;
- float time[4];
+ float time;
float delta;
uint64_t count;
@@ -1410,6 +1421,7 @@ public:
}
RasterizerStorageGLES3();
+ ~RasterizerStorageGLES3();
};
inline bool RasterizerStorageGLES3::safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const {
@@ -1445,10 +1457,9 @@ inline void RasterizerStorageGLES3::buffer_orphan_and_upload(unsigned int p_buff
}
#endif
}
- RAST_DEV_DEBUG_ASSERT((p_offset + p_data_size) <= p_buffer_size);
glBufferSubData(p_target, p_offset, p_data_size, p_data);
}
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
#endif // RASTERIZER_STORAGE_OPENGL_H
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
deleted file mode 100644
index 555ed6ebd2..0000000000
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ /dev/null
@@ -1,1136 +0,0 @@
-/*************************************************************************/
-/* shader_compiler_gles3.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 "shader_compiler_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
-
-#include "core/config/project_settings.h"
-#include "core/os/os.h"
-#include "core/string/string_buffer.h"
-#include "core/string/string_builder.h"
-
-#define SL ShaderLanguage
-
-static String _mktab(int p_level) {
- String tb;
- for (int i = 0; i < p_level; i++) {
- tb += "\t";
- }
-
- return tb;
-}
-
-static String _typestr(SL::DataType p_type) {
- return ShaderLanguage::get_datatype_name(p_type);
-}
-
-static String _prestr(SL::DataPrecision p_pres) {
- switch (p_pres) {
- case SL::PRECISION_LOWP:
- return "lowp ";
- case SL::PRECISION_MEDIUMP:
- return "mediump ";
- case SL::PRECISION_HIGHP:
- return "highp ";
- case SL::PRECISION_DEFAULT:
- return "";
- }
- return "";
-}
-
-static String _constr(bool p_is_const) {
- if (p_is_const) {
- return "const ";
- }
- return "";
-}
-
-static String _qualstr(SL::ArgumentQualifier p_qual) {
- switch (p_qual) {
- case SL::ARGUMENT_QUALIFIER_IN:
- return "in ";
- case SL::ARGUMENT_QUALIFIER_OUT:
- return "out ";
- case SL::ARGUMENT_QUALIFIER_INOUT:
- return "inout ";
- }
- return "";
-}
-
-static String _opstr(SL::Operator p_op) {
- return SL::get_operator_text(p_op);
-}
-
-static String _mkid(const String &p_id) {
- String id = "m_" + p_id.replace("__", "_dus_");
- return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
-}
-
-static String f2sp0(float p_float) {
- String num = rtoss(p_float);
- if (num.find(".") == -1 && num.find("e") == -1) {
- num += ".0";
- }
- return num;
-}
-
-static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) {
- switch (p_type) {
- case SL::TYPE_BOOL:
- return p_values[0].boolean ? "true" : "false";
- case SL::TYPE_BVEC2:
- case SL::TYPE_BVEC3:
- case SL::TYPE_BVEC4: {
- StringBuffer<> text;
-
- text += "bvec";
- text += itos(p_type - SL::TYPE_BOOL + 1);
- text += "(";
-
- for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
- text += ",";
-
- text += p_values[i].boolean ? "true" : "false";
- }
- text += ")";
- return text.as_string();
- }
-
- // GLSL ES 2 doesn't support uints, so we just use signed ints instead...
- case SL::TYPE_UINT:
- return itos(p_values[0].uint);
- case SL::TYPE_UVEC2:
- case SL::TYPE_UVEC3:
- case SL::TYPE_UVEC4: {
- StringBuffer<> text;
-
- text += "ivec";
- text += itos(p_type - SL::TYPE_UINT + 1);
- text += "(";
-
- for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
- text += ",";
-
- text += itos(p_values[i].uint);
- }
- text += ")";
- return text.as_string();
-
- } break;
-
- case SL::TYPE_INT:
- return itos(p_values[0].sint);
- case SL::TYPE_IVEC2:
- case SL::TYPE_IVEC3:
- case SL::TYPE_IVEC4: {
- StringBuffer<> text;
-
- text += "ivec";
- text += itos(p_type - SL::TYPE_INT + 1);
- text += "(";
-
- for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
- text += ",";
-
- text += itos(p_values[i].sint);
- }
- text += ")";
- return text.as_string();
-
- } break;
- case SL::TYPE_FLOAT:
- return f2sp0(p_values[0].real);
- case SL::TYPE_VEC2:
- case SL::TYPE_VEC3:
- case SL::TYPE_VEC4: {
- StringBuffer<> text;
-
- text += "vec";
- text += itos(p_type - SL::TYPE_FLOAT + 1);
- text += "(";
-
- for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
- text += ",";
-
- text += f2sp0(p_values[i].real);
- }
- text += ")";
- return text.as_string();
-
- } break;
- case SL::TYPE_MAT2:
- case SL::TYPE_MAT3:
- case SL::TYPE_MAT4: {
- StringBuffer<> text;
-
- text += "mat";
- text += itos(p_type - SL::TYPE_MAT2 + 2);
- text += "(";
-
- for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
- text += ",";
-
- text += f2sp0(p_values[i].real);
- }
- text += ")";
- return text.as_string();
-
- } break;
- default:
- ERR_FAIL_V(String());
- }
-}
-
-void ShaderCompilerGLES3::_dump_function_deps(SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added) {
- int fidx = -1;
-
- for (int i = 0; i < p_node->functions.size(); i++) {
- if (p_node->functions[i].name == p_for_func) {
- fidx = i;
- break;
- }
- }
-
- ERR_FAIL_COND(fidx == -1);
-
- for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) {
- if (r_added.has(E->get())) {
- continue;
- }
-
- _dump_function_deps(p_node, E->get(), p_func_code, r_to_add, r_added);
-
- SL::FunctionNode *fnode = NULL;
-
- for (int i = 0; i < p_node->functions.size(); i++) {
- if (p_node->functions[i].name == E->get()) {
- fnode = p_node->functions[i].function;
- break;
- }
- }
-
- ERR_FAIL_COND(!fnode);
-
- r_to_add += "\n";
-
- StringBuffer<128> header;
-
- header += _typestr(fnode->return_type);
- header += " ";
- header += _mkid(fnode->name);
- header += "(";
-
- for (int i = 0; i < fnode->arguments.size(); i++) {
- if (i > 0) {
- header += ", ";
- }
- header += _constr(fnode->arguments[i].is_const);
- header += _qualstr(fnode->arguments[i].qualifier);
- header += _prestr(fnode->arguments[i].precision);
- header += _typestr(fnode->arguments[i].type);
- header += " ";
- header += _mkid(fnode->arguments[i].name);
- }
-
- header += ")\n";
- r_to_add += header.as_string();
- r_to_add += p_func_code[E->get()];
-
- r_added.insert(E->get());
- }
-}
-
-String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
- StringBuilder code;
-
- switch (p_node->type) {
- default: {
- } break;
- case SL::Node::TYPE_SHADER: {
- SL::ShaderNode *snode = (SL::ShaderNode *)p_node;
-
- for (int i = 0; i < snode->render_modes.size(); i++) {
- if (p_default_actions.render_mode_defines.has(snode->render_modes[i]) && !used_rmode_defines.has(snode->render_modes[i])) {
- r_gen_code.custom_defines.push_back(p_default_actions.render_mode_defines[snode->render_modes[i]].utf8());
- used_rmode_defines.insert(snode->render_modes[i]);
- }
-
- if (p_actions.render_mode_flags.has(snode->render_modes[i])) {
- *p_actions.render_mode_flags[snode->render_modes[i]] = true;
- }
-
- if (p_actions.render_mode_values.has(snode->render_modes[i])) {
- Pair<int *, int> &p = p_actions.render_mode_values[snode->render_modes[i]];
- *p.first = p.second;
- }
- }
-
- int max_texture_uniforms = 0;
- int max_uniforms = 0;
-
- for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) {
- if (SL::is_sampler_type(E->get().type))
- max_texture_uniforms++;
- else
- max_uniforms++;
- }
-
- r_gen_code.texture_uniforms.resize(max_texture_uniforms);
- r_gen_code.texture_hints.resize(max_texture_uniforms);
-
- r_gen_code.uniforms.resize(max_uniforms + max_texture_uniforms);
-
- StringBuilder vertex_global;
- StringBuilder fragment_global;
-
- // uniforms
-
- for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) {
- StringBuffer<> uniform_code;
-
- // use highp if no precision is specified to prevent different default values in fragment and vertex shader
- SL::DataPrecision precision = E->get().precision;
- if (precision == SL::PRECISION_DEFAULT && E->get().type != SL::TYPE_BOOL) {
- precision = SL::PRECISION_HIGHP;
- }
-
- uniform_code += "uniform ";
- uniform_code += _prestr(precision);
- uniform_code += _typestr(E->get().type);
- uniform_code += " ";
- uniform_code += _mkid(E->key());
- uniform_code += ";\n";
-
- if (SL::is_sampler_type(E->get().type)) {
- r_gen_code.texture_uniforms.write[E->get().texture_order] = E->key();
- r_gen_code.texture_hints.write[E->get().texture_order] = E->get().hint;
- } else {
- r_gen_code.uniforms.write[E->get().order] = E->key();
- }
-
- vertex_global += uniform_code.as_string();
- fragment_global += uniform_code.as_string();
-
- p_actions.uniforms->insert(E->key(), E->get());
- }
-
- // varyings
-
- for (Map<StringName, SL::ShaderNode::Varying>::Element *E = snode->varyings.front(); E; E = E->next()) {
- StringBuffer<> varying_code;
-
- varying_code += "varying ";
- varying_code += _prestr(E->get().precision);
- varying_code += _typestr(E->get().type);
- varying_code += " ";
- varying_code += _mkid(E->key());
- if (E->get().array_size > 0) {
- varying_code += "[";
- varying_code += itos(E->get().array_size);
- varying_code += "]";
- }
- varying_code += ";\n";
-
- String final_code = varying_code.as_string();
-
- vertex_global += final_code;
- fragment_global += final_code;
- }
-
- // constants
-
- for (int i = 0; i < snode->vconstants.size(); i++) {
- String gcode;
- gcode += _constr(true);
- gcode += _prestr(snode->vconstants[i].precision);
- gcode += _typestr(snode->vconstants[i].type);
- gcode += " " + _mkid(String(snode->vconstants[i].name));
- gcode += "=";
- gcode += _dump_node_code(snode->vconstants[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- gcode += ";\n";
- vertex_global += gcode;
- fragment_global += gcode;
- }
-
- // functions
-
- Map<StringName, String> function_code;
-
- for (int i = 0; i < snode->functions.size(); i++) {
- SL::FunctionNode *fnode = snode->functions[i].function;
- current_func_name = fnode->name;
- function_code[fnode->name] = _dump_node_code(fnode->body, 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- }
-
- Set<StringName> added_vertex;
- Set<StringName> added_fragment;
-
- for (int i = 0; i < snode->functions.size(); i++) {
- SL::FunctionNode *fnode = snode->functions[i].function;
-
- current_func_name = fnode->name;
-
- if (fnode->name == vertex_name) {
- _dump_function_deps(snode, fnode->name, function_code, vertex_global, added_vertex);
- r_gen_code.vertex = function_code[vertex_name];
-
- } else if (fnode->name == fragment_name) {
- _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment);
- r_gen_code.fragment = function_code[fragment_name];
-
- } else if (fnode->name == light_name) {
- _dump_function_deps(snode, fnode->name, function_code, fragment_global, added_fragment);
- r_gen_code.light = function_code[light_name];
- }
- }
-
- r_gen_code.vertex_global = vertex_global.as_string();
- r_gen_code.fragment_global = fragment_global.as_string();
-
- } break;
-
- case SL::Node::TYPE_FUNCTION: {
- } break;
-
- case SL::Node::TYPE_BLOCK: {
- SL::BlockNode *bnode = (SL::BlockNode *)p_node;
-
- if (!bnode->single_statement) {
- code += _mktab(p_level - 1);
- code += "{\n";
- }
-
- for (int i = 0; i < bnode->statements.size(); i++) {
- String statement_code = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
-
- if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) {
- code += statement_code;
- } else {
- code += _mktab(p_level);
- code += statement_code;
- code += ";\n";
- }
- }
-
- if (!bnode->single_statement) {
- code += _mktab(p_level - 1);
- code += "}\n";
- }
- } break;
-
- case SL::Node::TYPE_VARIABLE_DECLARATION: {
- SL::VariableDeclarationNode *var_dec_node = (SL::VariableDeclarationNode *)p_node;
-
- StringBuffer<> declaration;
- declaration += _constr(var_dec_node->is_const);
- declaration += _prestr(var_dec_node->precision);
- declaration += _typestr(var_dec_node->datatype);
-
- for (int i = 0; i < var_dec_node->declarations.size(); i++) {
- if (i > 0) {
- declaration += ",";
- }
-
- declaration += " ";
-
- declaration += _mkid(var_dec_node->declarations[i].name);
-
- if (var_dec_node->declarations[i].initializer) {
- declaration += " = ";
- declaration += _dump_node_code(var_dec_node->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- }
- }
-
- code += declaration.as_string();
- } break;
-
- case SL::Node::TYPE_VARIABLE: {
- SL::VariableNode *var_node = (SL::VariableNode *)p_node;
-
- if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) {
- *p_actions.write_flag_pointers[var_node->name] = true;
- }
-
- if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) {
- String define = p_default_actions.usage_defines[var_node->name];
- String node_name = define.substr(1, define.length());
-
- if (define.begins_with("@")) {
- define = p_default_actions.usage_defines[node_name];
- }
-
- if (!used_name_defines.has(node_name)) {
- r_gen_code.custom_defines.push_back(define.utf8());
- }
- used_name_defines.insert(var_node->name);
- }
-
- if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) {
- *p_actions.usage_flag_pointers[var_node->name] = true;
- used_flag_pointers.insert(var_node->name);
- }
-
- if (p_default_actions.renames.has(var_node->name)) {
- code += p_default_actions.renames[var_node->name];
- } else {
- code += _mkid(var_node->name);
- }
-
- if (var_node->name == time_name) {
- if (current_func_name == vertex_name) {
- r_gen_code.uses_vertex_time = true;
- }
- if (current_func_name == fragment_name || current_func_name == light_name) {
- r_gen_code.uses_fragment_time = true;
- }
- }
- } break;
- case SL::Node::TYPE_ARRAY_DECLARATION: {
- SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
-
- StringBuffer<> declaration;
- declaration += _prestr(arr_dec_node->precision);
- declaration += _typestr(arr_dec_node->datatype);
-
- for (int i = 0; i < arr_dec_node->declarations.size(); i++) {
- if (i > 0) {
- declaration += ",";
- }
-
- declaration += " ";
-
- declaration += _mkid(arr_dec_node->declarations[i].name);
- declaration += "[";
- declaration += itos(arr_dec_node->declarations[i].size);
- declaration += "]";
- }
-
- code += declaration.as_string();
- } break;
- case SL::Node::TYPE_ARRAY: {
- SL::ArrayNode *arr_node = (SL::ArrayNode *)p_node;
-
- if (p_assigning && p_actions.write_flag_pointers.has(arr_node->name)) {
- *p_actions.write_flag_pointers[arr_node->name] = true;
- }
-
- if (p_default_actions.usage_defines.has(arr_node->name) && !used_name_defines.has(arr_node->name)) {
- String define = p_default_actions.usage_defines[arr_node->name];
- String node_name = define.substr(1, define.length());
-
- if (define.begins_with("@")) {
- define = p_default_actions.usage_defines[node_name];
- }
-
- if (!used_name_defines.has(node_name)) {
- r_gen_code.custom_defines.push_back(define.utf8());
- }
- used_name_defines.insert(arr_node->name);
- }
-
- if (p_actions.usage_flag_pointers.has(arr_node->name) && !used_flag_pointers.has(arr_node->name)) {
- *p_actions.usage_flag_pointers[arr_node->name] = true;
- used_flag_pointers.insert(arr_node->name);
- }
-
- if (p_default_actions.renames.has(arr_node->name)) {
- code += p_default_actions.renames[arr_node->name];
- } else {
- code += _mkid(arr_node->name);
- }
-
- if (arr_node->call_expression != NULL) {
- code += ".";
- code += _dump_node_code(arr_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning, false);
- }
-
- if (arr_node->index_expression != NULL) {
- code += "[";
- code += _dump_node_code(arr_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "]";
- }
-
- if (arr_node->name == time_name) {
- if (current_func_name == vertex_name) {
- r_gen_code.uses_vertex_time = true;
- }
- if (current_func_name == fragment_name || current_func_name == light_name) {
- r_gen_code.uses_fragment_time = true;
- }
- }
-
- } break;
- case SL::Node::TYPE_CONSTANT: {
- SL::ConstantNode *const_node = (SL::ConstantNode *)p_node;
-
- return get_constant_text(const_node->datatype, const_node->values);
- } break;
-
- case SL::Node::TYPE_OPERATOR: {
- SL::OperatorNode *op_node = (SL::OperatorNode *)p_node;
-
- switch (op_node->op) {
- case SL::OP_ASSIGN:
- case SL::OP_ASSIGN_ADD:
- case SL::OP_ASSIGN_SUB:
- case SL::OP_ASSIGN_MUL:
- case SL::OP_ASSIGN_DIV:
- case SL::OP_ASSIGN_SHIFT_LEFT:
- case SL::OP_ASSIGN_SHIFT_RIGHT:
- case SL::OP_ASSIGN_BIT_AND:
- case SL::OP_ASSIGN_BIT_OR:
- case SL::OP_ASSIGN_BIT_XOR: {
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, true);
- code += " ";
- code += _opstr(op_node->op);
- code += " ";
- code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- } break;
-
- case SL::OP_ASSIGN_MOD: {
- String a = _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- String n = _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += a + " = " + n + " == 0 ? 0 : ";
- code += a + " - " + n + " * (" + a + " / " + n + ")";
- } break;
-
- case SL::OP_BIT_INVERT:
- case SL::OP_NEGATE:
- case SL::OP_NOT:
- case SL::OP_DECREMENT:
- case SL::OP_INCREMENT: {
- code += _opstr(op_node->op);
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- } break;
-
- case SL::OP_POST_DECREMENT:
- case SL::OP_POST_INCREMENT: {
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += _opstr(op_node->op);
- } break;
-
- case SL::OP_CALL:
- case SL::OP_CONSTRUCT: {
- ERR_FAIL_COND_V(op_node->arguments[0]->type != SL::Node::TYPE_VARIABLE, String());
-
- SL::VariableNode *var_node = (SL::VariableNode *)op_node->arguments[0];
-
- if (op_node->op == SL::OP_CONSTRUCT) {
- code += var_node->name;
- } else {
- if (var_node->name == "texture") {
- // emit texture call
-
- if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) { // ||
- // op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLEREXT) {
- code += "texture";
- } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) {
- code += "textureCube";
- }
-
- } else if (var_node->name == "textureLod") {
- // emit texture call
-
- if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLER2D) {
- code += "textureLod";
- } else if (op_node->arguments[1]->get_datatype() == SL::TYPE_SAMPLERCUBE) {
- code += "textureCubeLod";
- }
-
- } else if (var_node->name == "mix") {
- switch (op_node->arguments[3]->get_datatype()) {
- case SL::TYPE_BVEC2: {
- code += "select2";
- } break;
-
- case SL::TYPE_BVEC3: {
- code += "select3";
- } break;
-
- case SL::TYPE_BVEC4: {
- code += "select4";
- } break;
-
- case SL::TYPE_VEC2:
- case SL::TYPE_VEC3:
- case SL::TYPE_VEC4:
- case SL::TYPE_FLOAT: {
- code += "mix";
- } break;
-
- default: {
- SL::DataType type = op_node->arguments[3]->get_datatype();
- // FIXME: Proper error print or graceful handling
- print_line(String("uhhhh invalid mix with type: ") + itos(type));
- } break;
- }
-
- } else if (p_default_actions.renames.has(var_node->name)) {
- code += p_default_actions.renames[var_node->name];
- } else if (internal_functions.has(var_node->name)) {
- code += var_node->name;
- } else {
- code += _mkid(var_node->name);
- }
- }
-
- code += "(";
-
- for (int i = 1; i < op_node->arguments.size(); i++) {
- if (i > 1) {
- code += ", ";
- }
-
- code += _dump_node_code(op_node->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- }
-
- code += ")";
-
- if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) {
- String define = p_default_actions.usage_defines[var_node->name];
- String node_name = define.substr(1, define.length());
-
- if (define.begins_with("@")) {
- define = p_default_actions.usage_defines[node_name];
- }
-
- if (!used_name_defines.has(node_name)) {
- r_gen_code.custom_defines.push_back(define.utf8());
- }
- used_name_defines.insert(var_node->name);
- }
-
- } break;
-
- case SL::OP_INDEX: {
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "[";
- code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "]";
- } break;
-
- case SL::OP_SELECT_IF: {
- code += "(";
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += " ? ";
- code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += " : ";
- code += _dump_node_code(op_node->arguments[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")";
- } break;
-
- case SL::OP_MOD: {
- String a = _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- String n = _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "(" + n + " == 0 ? 0 : ";
- code += a + " - " + n + " * (" + a + " / " + n + "))";
- } break;
-
- case SL::OP_EMPTY: {
- // Semicolon (or empty statement) - ignored.
- } break;
-
- default: {
- if (p_use_scope) {
- code += "(";
- }
- code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += " ";
- code += _opstr(op_node->op);
- code += " ";
- code += _dump_node_code(op_node->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- if (p_use_scope) {
- code += ")";
- }
- } break;
- }
- } break;
-
- case SL::Node::TYPE_CONTROL_FLOW: {
- SL::ControlFlowNode *cf_node = (SL::ControlFlowNode *)p_node;
-
- if (cf_node->flow_op == SL::FLOW_OP_IF) {
- code += _mktab(p_level);
- code += "if (";
- code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")\n";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
-
- if (cf_node->blocks.size() == 2) {
- code += _mktab(p_level);
- code += "else\n";
- code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- }
- } else if (cf_node->flow_op == SL::FLOW_OP_DO) {
- code += _mktab(p_level);
- code += "do";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += _mktab(p_level);
- code += "while (";
- code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ");";
- } else if (cf_node->flow_op == SL::FLOW_OP_WHILE) {
- code += _mktab(p_level);
- code += "while (";
- code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")\n";
- code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
- } else if (cf_node->flow_op == SL::FLOW_OP_FOR) {
- code += _mktab(p_level);
- code += "for (";
- code += _dump_node_code(cf_node->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "; ";
- code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += "; ";
- code += _dump_node_code(cf_node->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ")\n";
-
- code += _dump_node_code(cf_node->blocks[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
-
- } else if (cf_node->flow_op == SL::FLOW_OP_RETURN) {
- code += _mktab(p_level);
- code += "return";
-
- if (cf_node->expressions.size()) {
- code += " ";
- code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- }
- code += ";\n";
- } else if (cf_node->flow_op == SL::FLOW_OP_DISCARD) {
- if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) {
- *p_actions.usage_flag_pointers["DISCARD"] = true;
- used_flag_pointers.insert("DISCARD");
- }
- code += "discard;";
- } else if (cf_node->flow_op == SL::FLOW_OP_CONTINUE) {
- code += "continue;";
- } else if (cf_node->flow_op == SL::FLOW_OP_BREAK) {
- code += "break;";
- }
- } break;
-
- case SL::Node::TYPE_MEMBER: {
- SL::MemberNode *member_node = (SL::MemberNode *)p_node;
- code += _dump_node_code(member_node->owner, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- code += ".";
- code += member_node->name;
- } break;
- }
-
- return code.as_string();
-}
-
-ShaderLanguage::DataType ShaderCompilerGLES3::_get_variable_type(const StringName &p_type) {
- // RS::GlobalVariableType gvt = ((RasterizerStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
- RS::GlobalVariableType gvt = RS::GLOBAL_VAR_TYPE_MAX;
- return RS::global_variable_type_get_shader_datatype(gvt);
-}
-
-Error ShaderCompilerGLES3::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
- ShaderLanguage::VaryingFunctionNames var_names;
-
- ShaderLanguage::ShaderCompileInfo info;
- info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
- info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
- info.shader_types = ShaderTypes::get_singleton()->get_types();
- info.global_variable_type_func = _get_variable_type;
-
- Error err = parser.compile(p_code, info);
-
- // Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
- if (err != OK) {
- Vector<String> shader = p_code.split("\n");
- for (int i = 0; i < shader.size(); i++) {
- print_line(itos(i + 1) + " " + shader[i]);
- }
-
- _err_print_error(NULL, p_path.utf8().get_data(), parser.get_error_line(), parser.get_error_text().utf8().get_data(), false, ERR_HANDLER_SHADER);
- return err;
- }
-
- r_gen_code.custom_defines.clear();
- r_gen_code.uniforms.clear();
- r_gen_code.texture_uniforms.clear();
- r_gen_code.texture_hints.clear();
- r_gen_code.vertex = String();
- r_gen_code.vertex_global = String();
- r_gen_code.fragment = String();
- r_gen_code.fragment_global = String();
- r_gen_code.light = String();
- r_gen_code.uses_fragment_time = false;
- r_gen_code.uses_vertex_time = false;
-
- used_name_defines.clear();
- used_rmode_defines.clear();
- used_flag_pointers.clear();
-
- _dump_node_code(parser.get_shader(), 1, r_gen_code, *p_actions, actions[p_mode], false);
-
- return OK;
-}
-
-ShaderCompilerGLES3::ShaderCompilerGLES3() {
- /** CANVAS ITEM SHADER **/
-
- actions[RS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
- actions[RS::SHADER_CANVAS_ITEM].renames["UV"] = "uv";
- actions[RS::SHADER_CANVAS_ITEM].renames["POINT_SIZE"] = "point_size";
-
- actions[RS::SHADER_CANVAS_ITEM].renames["WORLD_MATRIX"] = "modelview_matrix";
- actions[RS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions[RS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] = "extra_matrix_instance";
- actions[RS::SHADER_CANVAS_ITEM].renames["TIME"] = "time";
- actions[RS::SHADER_CANVAS_ITEM].renames["PI"] = _MKSTR(Math_PI);
- actions[RS::SHADER_CANVAS_ITEM].renames["TAU"] = _MKSTR(Math_TAU);
- actions[RS::SHADER_CANVAS_ITEM].renames["E"] = _MKSTR(Math_E);
- actions[RS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
- actions[RS::SHADER_CANVAS_ITEM].renames["INSTANCE_CUSTOM"] = "instance_custom";
-
- actions[RS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
- actions[RS::SHADER_CANVAS_ITEM].renames["MODULATE"] = "final_modulate";
- actions[RS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
- actions[RS::SHADER_CANVAS_ITEM].renames["NORMALMAP"] = "normal_map";
- actions[RS::SHADER_CANVAS_ITEM].renames["NORMALMAP_DEPTH"] = "normal_depth";
- actions[RS::SHADER_CANVAS_ITEM].renames["TEXTURE"] = "color_texture";
- actions[RS::SHADER_CANVAS_ITEM].renames["TEXTURE_PIXEL_SIZE"] = "color_texpixel_size";
- actions[RS::SHADER_CANVAS_ITEM].renames["NORMAL_TEXTURE"] = "normal_texture";
- actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_UV"] = "screen_uv";
- actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_TEXTURE"] = "screen_texture";
- actions[RS::SHADER_CANVAS_ITEM].renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size";
- actions[RS::SHADER_CANVAS_ITEM].renames["FRAGCOORD"] = "gl_FragCoord";
- actions[RS::SHADER_CANVAS_ITEM].renames["POINT_COORD"] = "gl_PointCoord";
-
- actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_VEC"] = "light_vec";
- actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_HEIGHT"] = "light_height";
- actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_COLOR"] = "light_color";
- actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
- actions[RS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
- actions[RS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
- actions[RS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
-
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["MODULATE"] = "#define MODULATE_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
- actions[RS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
-
- // Ported from GLES3
-
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["sinh"] = "#define SINH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["cosh"] = "#define COSH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["tanh"] = "#define TANH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["asinh"] = "#define ASINH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["acosh"] = "#define ACOSH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["atanh"] = "#define ATANH_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["round"] = "#define ROUND_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["inverse"] = "#define INVERSE_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["isinf"] = "#define IS_INF_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["isnan"] = "#define IS_NAN_USED\n";
- actions[RS::SHADER_CANVAS_ITEM].usage_defines["trunc"] = "#define TRUNC_USED\n";
-
- /** SPATIAL SHADER **/
-
- actions[RS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform";
- actions[RS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix";
- actions[RS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix";
- actions[RS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions[RS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "projection_inverse_matrix";
- actions[RS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview";
-
- actions[RS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz";
- actions[RS::SHADER_SPATIAL].renames["NORMAL"] = "normal";
- actions[RS::SHADER_SPATIAL].renames["TANGENT"] = "tangent";
- actions[RS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal";
- actions[RS::SHADER_SPATIAL].renames["POSITION"] = "position";
- actions[RS::SHADER_SPATIAL].renames["UV"] = "uv_interp";
- actions[RS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp";
- actions[RS::SHADER_SPATIAL].renames["COLOR"] = "color_interp";
- actions[RS::SHADER_SPATIAL].renames["POINT_SIZE"] = "point_size";
- // gl_InstanceID is not available in OpenGL ES 2.0
- actions[RS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "0";
-
- //builtins
-
- actions[RS::SHADER_SPATIAL].renames["TIME"] = "time";
- actions[RS::SHADER_SPATIAL].renames["PI"] = _MKSTR(Math_PI);
- actions[RS::SHADER_SPATIAL].renames["TAU"] = _MKSTR(Math_TAU);
- actions[RS::SHADER_SPATIAL].renames["E"] = _MKSTR(Math_E);
- actions[RS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size";
-
- actions[RS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord";
- actions[RS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing";
- actions[RS::SHADER_SPATIAL].renames["NORMALMAP"] = "normalmap";
- actions[RS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth";
- actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
- actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha";
- actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic";
- actions[RS::SHADER_SPATIAL].renames["SPECULAR"] = "specular";
- actions[RS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness";
- actions[RS::SHADER_SPATIAL].renames["RIM"] = "rim";
- actions[RS::SHADER_SPATIAL].renames["RIM_TINT"] = "rim_tint";
- actions[RS::SHADER_SPATIAL].renames["CLEARCOAT"] = "clearcoat";
- actions[RS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
- actions[RS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy";
- actions[RS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
- actions[RS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
- actions[RS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission";
- actions[RS::SHADER_SPATIAL].renames["AO"] = "ao";
- actions[RS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
- actions[RS::SHADER_SPATIAL].renames["EMISSION"] = "emission";
- actions[RS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
- actions[RS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
- actions[RS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
- actions[RS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
- actions[RS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_texture";
- // Defined in GLES3, but not available in GLES2
- //actions[RS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth";
- actions[RS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor";
- actions[RS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
-
- //for light
- actions[RS::SHADER_SPATIAL].renames["VIEW"] = "view";
- actions[RS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color";
- actions[RS::SHADER_SPATIAL].renames["LIGHT"] = "light";
- actions[RS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation";
- actions[RS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light";
- actions[RS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light";
-
- actions[RS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
- actions[RS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n";
- actions[RS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM";
- actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n";
- actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT";
- actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n";
- actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
- actions[RS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n";
- actions[RS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n";
- actions[RS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP"] = "#define ENABLE_NORMALMAP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"] = "@NORMALMAP";
- actions[RS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
- actions[RS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
- actions[RS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
-
- actions[RS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
- actions[RS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["DEPTH_TEXTURE"] = "#define DEPTH_TEXTURE_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
-
- actions[RS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
- actions[RS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
-
- // Ported from GLES3
-
- actions[RS::SHADER_SPATIAL].usage_defines["sinh"] = "#define SINH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["cosh"] = "#define COSH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["tanh"] = "#define TANH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["asinh"] = "#define ASINH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["acosh"] = "#define ACOSH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["atanh"] = "#define ATANH_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["determinant"] = "#define DETERMINANT_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["transpose"] = "#define TRANSPOSE_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["outerProduct"] = "#define OUTER_PRODUCT_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["round"] = "#define ROUND_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["roundEven"] = "#define ROUND_EVEN_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["inverse"] = "#define INVERSE_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["isinf"] = "#define IS_INF_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["isnan"] = "#define IS_NAN_USED\n";
- actions[RS::SHADER_SPATIAL].usage_defines["trunc"] = "#define TRUNC_USED\n";
-
- actions[RS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
-
- // Defined in GLES3, could be implemented in GLES2 too if there's a need for it
- //actions[RS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n";
- // Defined in GLES3, might not be possible in GLES2 as gl_FrontFacing is not available
- //actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
- //actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
-
- bool force_lambert = GLOBAL_GET("rendering/quality/shading/force_lambert_over_burley");
-
- if (!force_lambert) {
- actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
- }
-
- actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
-
- bool force_blinn = GLOBAL_GET("rendering/quality/shading/force_blinn_over_ggx");
-
- if (!force_blinn) {
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
- } else {
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n";
- }
-
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
- actions[RS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
-
- // No defines for particle shaders in OpenGL, there are no GPU particles
-
- vertex_name = "vertex";
- fragment_name = "fragment";
- light_name = "light";
- time_name = "TIME";
-
- List<String> func_list;
-
- ShaderLanguage::get_builtin_funcs(&func_list);
-
- for (List<String>::Element *E = func_list.front(); E; E = E->next()) {
- internal_functions.insert(E->get());
- }
-}
-
-#endif // GLES3_BACKEND_ENABLED
diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h
deleted file mode 100644
index 7ed882d03d..0000000000
--- a/drivers/gles3/shader_compiler_gles3.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*************************************************************************/
-/* shader_compiler_gles3.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 SHADER_COMPILER_OPENGL_H
-#define SHADER_COMPILER_OPENGL_H
-
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
-
-#include "core/string/string_builder.h"
-#include "core/templates/pair.h"
-#include "servers/rendering/shader_language.h"
-#include "servers/rendering/shader_types.h"
-#include "servers/rendering_server.h"
-
-class ShaderCompilerGLES3 {
-public:
- struct IdentifierActions {
- Map<StringName, Pair<int *, int>> render_mode_values;
- Map<StringName, bool *> render_mode_flags;
- Map<StringName, bool *> usage_flag_pointers;
- Map<StringName, bool *> write_flag_pointers;
-
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms;
- };
-
- struct GeneratedCode {
- Vector<CharString> custom_defines;
- Vector<StringName> uniforms;
- Vector<StringName> texture_uniforms;
- Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints;
-
- String vertex_global;
- String vertex;
- String fragment_global;
- String fragment;
- String light;
-
- bool uses_fragment_time;
- bool uses_vertex_time;
- };
-
-private:
- ShaderLanguage parser;
-
- struct DefaultIdentifierActions {
- Map<StringName, String> renames;
- Map<StringName, String> render_mode_defines;
- Map<StringName, String> usage_defines;
- };
-
- void _dump_function_deps(ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, StringBuilder &r_to_add, Set<StringName> &r_added);
- String _dump_node_code(ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope = true);
-
- StringName current_func_name;
- StringName vertex_name;
- StringName fragment_name;
- StringName light_name;
- StringName time_name;
-
- Set<StringName> used_name_defines;
- Set<StringName> used_flag_pointers;
- Set<StringName> used_rmode_defines;
- Set<StringName> internal_functions;
-
- DefaultIdentifierActions actions[RS::SHADER_MAX];
-
- // compatibility with godot 4
- static ShaderLanguage::DataType _get_variable_type(const StringName &p_type);
-
-public:
- Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
-
- ShaderCompilerGLES3();
-};
-
-#endif // GLES3_BACKEND_ENABLED
-
-#endif // SHADER_COMPILER_OPENGL_H
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 474a80aca1..7ae8b4e3bf 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -29,378 +29,305 @@
/*************************************************************************/
#include "shader_gles3.h"
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
-#include "rasterizer_gles3.h"
-#include "rasterizer_storage_gles3.h"
+#include "core/io/compression.h"
+#include "core/io/dir_access.h"
+#include "core/io/file_access.h"
-#include "core/config/project_settings.h"
-#include "core/os/memory.h"
-#include "core/string/print_string.h"
-#include "core/string/string_builder.h"
+void ShaderGLES3::_add_stage(const char *p_code, StageType p_stage_type) {
+ Vector<String> lines = String(p_code).split("\n");
-// #define DEBUG_OPENGL
+ String text;
-// #include "shaders/copy.glsl.gen.h"
+ for (int i = 0; i < lines.size(); i++) {
+ String l = lines[i];
+ bool push_chunk = false;
-#ifdef DEBUG_OPENGL
+ StageTemplate::Chunk chunk;
-#define DEBUG_TEST_ERROR(m_section) \
- { \
- uint32_t err = glGetError(); \
- if (err) { \
- print_line("OpenGL Error #" + itos(err) + " at: " + m_section); \
- } \
- }
-#else
-
-#define DEBUG_TEST_ERROR(m_section)
-
-#endif
-
-ShaderGLES3 *ShaderGLES3::active = NULL;
-
-//#define DEBUG_SHADER
-
-#ifdef DEBUG_SHADER
-
-#define DEBUG_PRINT(m_text) print_line(m_text);
-
-#else
-
-#define DEBUG_PRINT(m_text)
-
-#endif
-
-GLint ShaderGLES3::get_uniform_location(int p_index) const {
- ERR_FAIL_COND_V(!version, -1);
-
- return version->uniform_location[p_index];
-}
+ if (l.begins_with("#GLOBALS")) {
+ switch (p_stage_type) {
+ case STAGE_TYPE_VERTEX:
+ chunk.type = StageTemplate::Chunk::TYPE_VERTEX_GLOBALS;
+ break;
+ case STAGE_TYPE_FRAGMENT:
+ chunk.type = StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS;
+ break;
+ default: {
+ }
+ }
-bool ShaderGLES3::bind() {
- if (active != this || !version || new_conditional_version.key != conditional_version.key) {
- conditional_version = new_conditional_version;
- version = get_current_version();
- } else {
- return false;
- }
+ push_chunk = true;
+ } else if (l.begins_with("#MATERIAL_UNIFORMS")) {
+ chunk.type = StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS;
+ push_chunk = true;
+ } else if (l.begins_with("#CODE")) {
+ chunk.type = StageTemplate::Chunk::TYPE_CODE;
+ push_chunk = true;
+ chunk.code = l.replace_first("#CODE", String()).replace(":", "").strip_edges().to_upper();
+ } else {
+ text += l + "\n";
+ }
- ERR_FAIL_COND_V(!version, false);
+ if (push_chunk) {
+ if (text != String()) {
+ StageTemplate::Chunk text_chunk;
+ text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
+ text_chunk.text = text.utf8();
+ stage_templates[p_stage_type].chunks.push_back(text_chunk);
+ text = String();
+ }
+ stage_templates[p_stage_type].chunks.push_back(chunk);
+ }
- if (!version->ok) { //broken, unable to bind (do not throw error, you saw it before already when it failed compilation).
- glUseProgram(0);
- return false;
+ if (text != String()) {
+ StageTemplate::Chunk text_chunk;
+ text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
+ text_chunk.text = text.utf8();
+ stage_templates[p_stage_type].chunks.push_back(text_chunk);
+ text = String();
+ }
}
-
- glUseProgram(version->id);
-
- DEBUG_TEST_ERROR("use program");
-
- active = this;
- uniforms_dirty = true;
-
- return true;
}
-void ShaderGLES3::unbind() {
- version = NULL;
- glUseProgram(0);
- uniforms_dirty = true;
- active = NULL;
-}
-
-static void _display_error_with_code(const String &p_error, const Vector<const char *> &p_code) {
- int line = 1;
- String total_code;
+void ShaderGLES3::_setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants) {
+ name = p_name;
- for (int i = 0; i < p_code.size(); i++) {
- total_code += String(p_code[i]);
- }
-
- Vector<String> lines = String(total_code).split("\n");
-
- for (int j = 0; j < lines.size(); j++) {
- print_line(itos(line) + ": " + lines[j]);
- line++;
+ if (p_vertex_code) {
+ _add_stage(p_vertex_code, STAGE_TYPE_VERTEX);
}
-
- ERR_PRINT(p_error);
-}
-
-static String _mkid(const String &p_id) {
- String id = "m_" + p_id;
- return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
-}
-
-ShaderGLES3::Version *ShaderGLES3::get_current_version() {
- if (!valid)
- return nullptr;
-
- Version *_v = version_map.getptr(conditional_version);
-
- if (_v) {
- if (conditional_version.code_version != 0) {
- CustomCode *cc = custom_code_map.getptr(conditional_version.code_version);
- ERR_FAIL_COND_V(!cc, _v);
- if (cc->version == _v->code_version)
- return _v;
- } else {
- return _v;
- }
+ if (p_fragment_code) {
+ _add_stage(p_fragment_code, STAGE_TYPE_FRAGMENT);
}
- if (!_v)
- version_map[conditional_version] = Version();
-
- Version &v = version_map[conditional_version];
-
- if (!_v) {
- v.uniform_location = memnew_arr(GLint, uniform_count);
- } else {
- if (v.ok) {
- glDeleteShader(v.vert_id);
- glDeleteShader(v.frag_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ uniform_names = p_uniform_names;
+ uniform_count = p_uniform_count;
+ ubo_pairs = p_ubos;
+ ubo_count = p_ubo_count;
+ texunit_pairs = p_tex_units;
+ texunit_pair_count = p_texture_count;
+ specializations = p_specializations;
+ specialization_count = p_specialization_count;
+ specialization_default_mask = 0;
+ for (int i = 0; i < specialization_count; i++) {
+ if (specializations[i].default_value) {
+ specialization_default_mask |= (uint64_t(1) << uint64_t(i));
}
}
+ variant_defines = p_variants;
+ variant_count = p_variant_count;
+
+ StringBuilder tohash;
+ /*
+ tohash.append("[SpirvCacheKey]");
+ tohash.append(RenderingDevice::get_singleton()->shader_get_spirv_cache_key());
+ tohash.append("[BinaryCacheKey]");
+ tohash.append(RenderingDevice::get_singleton()->shader_get_binary_cache_key());
+ */
+ tohash.append("[Vertex]");
+ tohash.append(p_vertex_code ? p_vertex_code : "");
+ tohash.append("[Fragment]");
+ tohash.append(p_fragment_code ? p_fragment_code : "");
+
+ base_sha256 = tohash.as_string().sha256_text();
+}
- v.ok = false;
+RID ShaderGLES3::version_create() {
+ //initialize() was never called
+ ERR_FAIL_COND_V(variant_count == 0, RID());
- Vector<const char *> strings;
+ Version version;
+ return version_owner.make_rid(version);
+}
+void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization) {
#ifdef GLES_OVER_GL
- strings.push_back("#version 330\n");
- strings.push_back("#define USE_GLES_OVER_GL\n");
+ builder.append("#version 330\n");
+ builder.append("#define USE_GLES_OVER_GL\n");
#else
- strings.push_back("#version 300 es\n");
-//angle does not like
-#ifdef JAVASCRIPT_ENABLED
- strings.push_back("#define USE_HIGHP_PRECISION\n");
-#endif
-
- //if (GLOBAL_GET("rendering/opengl/compatibility/enable_high_float.Android")) {
- // enable USE_HIGHP_PRECISION but safeguarded by an availability check as highp support is optional in OpenGL
- // see Section 4.5.4 of the GLSL_ES_Specification_1.00
- //strings.push_back("#ifdef GL_FRAGMENT_PRECISION_HIGH\n #define USE_HIGHP_PRECISION\n#endif\n");
- //}
-
+ builder.append("#version 300 es\n");
#endif
-#ifdef ANDROID_ENABLED
- strings.push_back("#define ANDROID_ENABLED\n");
-#endif
-
- for (int i = 0; i < custom_defines.size(); i++) {
- strings.push_back(custom_defines[i].get_data());
- strings.push_back("\n");
- }
-
- for (int j = 0; j < conditional_count; j++) {
- bool enable = (conditional_version.version & (1 << j)) > 0;
-
- if (enable) {
- strings.push_back(conditional_defines[j]);
- DEBUG_PRINT(conditional_defines[j]);
+ for (int i = 0; i < specialization_count; i++) {
+ if (p_specialization & (uint64_t(1) << uint64_t(i))) {
+ builder.append("#define " + String(specializations[i].name) + "\n");
}
}
-
- // keep them around during the function
- CharString code_string;
- CharString code_string2;
- CharString code_globals;
-
- CustomCode *cc = NULL;
-
- if (conditional_version.code_version > 0) {
- cc = custom_code_map.getptr(conditional_version.code_version);
-
- ERR_FAIL_COND_V(!cc, NULL);
- v.code_version = cc->version;
- }
-
- // program
-
- v.id = glCreateProgram();
- ERR_FAIL_COND_V(v.id == 0, NULL);
-
- if (cc) {
- for (int i = 0; i < cc->custom_defines.size(); i++) {
- strings.push_back(cc->custom_defines.write[i]);
- DEBUG_PRINT("CD #" + itos(i) + ": " + String(cc->custom_defines[i].get_data()));
+ if (p_version->uniforms.size()) {
+ builder.append("#define MATERIAL_UNIFORMS_USED\n");
+ }
+ for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
+ builder.append(String("#define ") + String(E.key) + "_CODE_USED\n");
+ }
+
+ builder.append("\n"); //make sure defines begin at newline
+ builder.append(general_defines.get_data());
+ builder.append(variant_defines[p_variant]);
+ for (int j = 0; j < p_version->custom_defines.size(); j++) {
+ builder.append(p_version->custom_defines[j].get_data());
+ }
+ builder.append("\n"); //make sure defines begin at newline
+
+ for (uint32_t i = 0; i < p_template.chunks.size(); i++) {
+ const StageTemplate::Chunk &chunk = p_template.chunks[i];
+ switch (chunk.type) {
+ case StageTemplate::Chunk::TYPE_MATERIAL_UNIFORMS: {
+ builder.append(p_version->uniforms.get_data()); //uniforms (same for vertex and fragment)
+ } break;
+ case StageTemplate::Chunk::TYPE_VERTEX_GLOBALS: {
+ builder.append(p_version->vertex_globals.get_data()); // vertex globals
+ } break;
+ case StageTemplate::Chunk::TYPE_FRAGMENT_GLOBALS: {
+ builder.append(p_version->fragment_globals.get_data()); // fragment globals
+ } break;
+ case StageTemplate::Chunk::TYPE_CODE: {
+ if (p_version->code_sections.has(chunk.code)) {
+ builder.append(p_version->code_sections[chunk.code].get_data());
+ }
+ } break;
+ case StageTemplate::Chunk::TYPE_TEXT: {
+ builder.append(chunk.text.get_data());
+ } break;
}
}
+}
- // vertex shader
-
- int string_base_size = strings.size();
-
- strings.push_back(vertex_code0.get_data());
-
- if (cc) {
- code_globals = cc->vertex_globals.ascii();
- strings.push_back(code_globals.get_data());
- }
-
- strings.push_back(vertex_code1.get_data());
+static void _display_error_with_code(const String &p_error, const String &p_code) {
+ int line = 1;
+ Vector<String> lines = p_code.split("\n");
- if (cc) {
- code_string = cc->vertex.ascii();
- strings.push_back(code_string.get_data());
+ for (int j = 0; j < lines.size(); j++) {
+ print_line(itos(line) + ": " + lines[j]);
+ line++;
}
- strings.push_back(vertex_code2.get_data());
-
-#ifdef DEBUG_SHADER
-
- DEBUG_PRINT("\nVertex Code:\n\n" + String(code_string.get_data()));
-
-#endif
-
- v.vert_id = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(v.vert_id, strings.size(), &strings[0], NULL);
- glCompileShader(v.vert_id);
+ ERR_PRINT(p_error);
+}
+void ShaderGLES3::_compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization) {
+ spec.id = glCreateProgram();
+ spec.ok = false;
GLint status;
- glGetShaderiv(v.vert_id, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE) {
- GLsizei iloglen;
- glGetShaderiv(v.vert_id, GL_INFO_LOG_LENGTH, &iloglen);
-
- if (iloglen < 0) {
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ //vertex stage
+ {
+ StringBuilder builder;
+ _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_VERTEX], p_specialization);
+
+ spec.vert_id = glCreateShader(GL_VERTEX_SHADER);
+ String builder_string = builder.as_string();
+ CharString cs = builder_string.utf8();
+ const char *cstr = cs.ptr();
+ glShaderSource(spec.vert_id, 1, &cstr, nullptr);
+ glCompileShader(spec.vert_id);
+
+ glGetShaderiv(spec.vert_id, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) {
+ GLsizei iloglen;
+ glGetShaderiv(spec.vert_id, GL_INFO_LOG_LENGTH, &iloglen);
+
+ if (iloglen < 0) {
+ glDeleteShader(spec.vert_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
+
+ ERR_PRINT("No OpenGL vertex shader compiler log.");
+ } else {
+ if (iloglen == 0) {
+ iloglen = 4096; // buggy driver (Adreno 220+)
+ }
- ERR_PRINT("No OpenGL vertex shader compiler log. What the frick?");
- } else {
- if (iloglen == 0) {
- iloglen = 4096; // buggy driver (Adreno 220+)
- }
+ char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
+ ilogmem[iloglen] = '\0';
+ glGetShaderInfoLog(spec.vert_id, iloglen, &iloglen, ilogmem);
- char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
- ilogmem[iloglen] = '\0';
- glGetShaderInfoLog(v.vert_id, iloglen, &iloglen, ilogmem);
+ String err_string = name + ": Vertex shader compilation failed:\n";
- String err_string = get_shader_name() + ": Vertex shader compilation failed:\n";
+ err_string += ilogmem;
- err_string += ilogmem;
+ _display_error_with_code(err_string, builder_string);
- _display_error_with_code(err_string, strings);
+ Memory::free_static(ilogmem);
+ glDeleteShader(spec.vert_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
+ }
- Memory::free_static(ilogmem);
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ ERR_FAIL();
}
-
- ERR_FAIL_V(NULL);
- }
-
- strings.resize(string_base_size);
-
- // fragment shader
-
- strings.push_back(fragment_code0.get_data());
-
- if (cc) {
- code_globals = cc->fragment_globals.ascii();
- strings.push_back(code_globals.get_data());
- }
-
- strings.push_back(fragment_code1.get_data());
-
- if (cc) {
- code_string = cc->light.ascii();
- strings.push_back(code_string.get_data());
- }
-
- strings.push_back(fragment_code2.get_data());
-
- if (cc) {
- code_string2 = cc->fragment.ascii();
- strings.push_back(code_string2.get_data());
}
- strings.push_back(fragment_code3.get_data());
-
-#ifdef DEBUG_SHADER
+ //fragment stage
+ {
+ StringBuilder builder;
+ _build_variant_code(builder, p_variant, p_version, stage_templates[STAGE_TYPE_FRAGMENT], p_specialization);
+
+ spec.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
+ String builder_string = builder.as_string();
+ CharString cs = builder_string.utf8();
+ const char *cstr = cs.ptr();
+ glShaderSource(spec.frag_id, 1, &cstr, nullptr);
+ glCompileShader(spec.frag_id);
+
+ glGetShaderiv(spec.frag_id, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) {
+ GLsizei iloglen;
+ glGetShaderiv(spec.frag_id, GL_INFO_LOG_LENGTH, &iloglen);
+
+ if (iloglen < 0) {
+ glDeleteShader(spec.frag_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
+
+ ERR_PRINT("No OpenGL fragment shader compiler log.");
+ } else {
+ if (iloglen == 0) {
+ iloglen = 4096; // buggy driver (Adreno 220+)
+ }
- if (cc) {
- DEBUG_PRINT("\nFragment Code:\n\n" + String(cc->fragment_globals));
- }
- DEBUG_PRINT("\nFragment Code:\n\n" + String(code_string.get_data()));
-#endif
+ char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
+ ilogmem[iloglen] = '\0';
+ glGetShaderInfoLog(spec.frag_id, iloglen, &iloglen, ilogmem);
- v.frag_id = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(v.frag_id, strings.size(), &strings[0], NULL);
- glCompileShader(v.frag_id);
+ String err_string = name + ": Fragment shader compilation failed:\n";
- glGetShaderiv(v.frag_id, GL_COMPILE_STATUS, &status);
- if (status == GL_FALSE) {
- GLsizei iloglen;
- glGetShaderiv(v.frag_id, GL_INFO_LOG_LENGTH, &iloglen);
+ err_string += ilogmem;
- if (iloglen < 0) {
- glDeleteShader(v.frag_id);
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ _display_error_with_code(err_string, builder_string);
- ERR_PRINT("No OpenGL fragment shader compiler log. What the frick?");
- } else {
- if (iloglen == 0) {
- iloglen = 4096; // buggy driver (Adreno 220+)
+ Memory::free_static(ilogmem);
+ glDeleteShader(spec.frag_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
}
- char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
- ilogmem[iloglen] = '\0';
- glGetShaderInfoLog(v.frag_id, iloglen, &iloglen, ilogmem);
-
- String err_string = get_shader_name() + ": Fragment shader compilation failed:\n";
-
- err_string += ilogmem;
-
- _display_error_with_code(err_string, strings);
-
- Memory::free_static(ilogmem);
- glDeleteShader(v.frag_id);
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ ERR_FAIL();
}
-
- ERR_FAIL_V(NULL);
}
- glAttachShader(v.id, v.frag_id);
- glAttachShader(v.id, v.vert_id);
+ glAttachShader(spec.id, spec.frag_id);
+ glAttachShader(spec.id, spec.vert_id);
- // bind the attribute locations. This has to be done before linking so that the
- // linker doesn't assign some random indices
-
- for (int i = 0; i < attribute_pair_count; i++) {
- glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
- }
+ //for (int i = 0; i < attribute_pair_count; i++) {
+ // glBindAttribLocation(v.id, attribute_pairs[i].index, attribute_pairs[i].name);
+ //}
- glLinkProgram(v.id);
+ glLinkProgram(spec.id);
- glGetProgramiv(v.id, GL_LINK_STATUS, &status);
+ glGetProgramiv(spec.id, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLsizei iloglen;
- glGetProgramiv(v.id, GL_INFO_LOG_LENGTH, &iloglen);
+ glGetProgramiv(spec.id, GL_INFO_LOG_LENGTH, &iloglen);
if (iloglen < 0) {
- glDeleteShader(v.frag_id);
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ glDeleteShader(spec.frag_id);
+ glDeleteShader(spec.vert_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
ERR_PRINT("No OpenGL program link log. What the frick?");
- ERR_FAIL_V(NULL);
+ ERR_FAIL();
}
if (iloglen == 0) {
@@ -409,33 +336,34 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
char *ilogmem = (char *)Memory::alloc_static(iloglen + 1);
ilogmem[iloglen] = '\0';
- glGetProgramInfoLog(v.id, iloglen, &iloglen, ilogmem);
+ glGetProgramInfoLog(spec.id, iloglen, &iloglen, ilogmem);
- String err_string = get_shader_name() + ": Program linking failed:\n";
+ String err_string = name + ": Program linking failed:\n";
err_string += ilogmem;
- _display_error_with_code(err_string, strings);
+ _display_error_with_code(err_string, String());
Memory::free_static(ilogmem);
- glDeleteShader(v.frag_id);
- glDeleteShader(v.vert_id);
- glDeleteProgram(v.id);
- v.id = 0;
+ glDeleteShader(spec.frag_id);
+ glDeleteShader(spec.vert_id);
+ glDeleteProgram(spec.id);
+ spec.id = 0;
- ERR_FAIL_V(NULL);
+ ERR_FAIL();
}
// get uniform locations
- glUseProgram(v.id);
+ glUseProgram(spec.id);
+ spec.uniform_location.resize(uniform_count);
for (int i = 0; i < uniform_count; i++) {
- v.uniform_location[i] = glGetUniformLocation(v.id, uniform_names[i]);
+ spec.uniform_location[i] = glGetUniformLocation(spec.id, uniform_names[i]);
}
for (int i = 0; i < texunit_pair_count; i++) {
- GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name);
+ GLint loc = glGetUniformLocation(spec.id, texunit_pairs[i].name);
if (loc >= 0) {
if (texunit_pairs[i].index < 0) {
glUniform1i(loc, max_image_units + texunit_pairs[i].index);
@@ -445,672 +373,330 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
}
}
- if (cc) {
- // uniforms
- for (int i = 0; i < cc->custom_uniforms.size(); i++) {
- String native_uniform_name = _mkid(cc->custom_uniforms[i]);
- GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
- v.custom_uniform_locations[cc->custom_uniforms[i]] = location;
- }
-
- // textures
- for (int i = 0; i < cc->texture_uniforms.size(); i++) {
- String native_uniform_name = _mkid(cc->texture_uniforms[i]);
- GLint location = glGetUniformLocation(v.id, (native_uniform_name).ascii().get_data());
- v.custom_uniform_locations[cc->texture_uniforms[i]] = location;
- glUniform1i(location, i);
+ for (int i = 0; i < ubo_count; i++) {
+ GLint loc = glGetUniformBlockIndex(spec.id, ubo_pairs[i].name);
+ if (loc >= 0) {
+ glUniformBlockBinding(spec.id, loc, ubo_pairs[i].index);
}
}
-
- glUseProgram(0);
- v.ok = true;
-
- if (cc) {
- cc->versions.insert(conditional_version.version);
+ // textures
+ for (int i = 0; i < p_version->texture_uniforms.size(); i++) {
+ String native_uniform_name = p_version->texture_uniforms[i];
+ GLint location = glGetUniformLocation(spec.id, (native_uniform_name).ascii().get_data());
+ glUniform1i(location, i + base_texture_index);
}
- return &v;
+ glUseProgram(0);
+ spec.ok = true;
}
-GLint ShaderGLES3::get_uniform_location(const String &p_name) const {
- ERR_FAIL_COND_V(!version, -1);
- return glGetUniformLocation(version->id, p_name.ascii().get_data());
-}
+RS::ShaderNativeSourceCode ShaderGLES3::version_get_native_source_code(RID p_version) {
+ Version *version = version_owner.get_or_null(p_version);
+ RS::ShaderNativeSourceCode source_code;
+ ERR_FAIL_COND_V(!version, source_code);
-void ShaderGLES3::setup(
- const char **p_conditional_defines,
- int p_conditional_count,
- const char **p_uniform_names,
- int p_uniform_count,
- const AttributePair *p_attribute_pairs,
- int p_attribute_count,
- const TexUnitPair *p_texunit_pairs,
- int p_texunit_pair_count,
- const char *p_vertex_code,
- const char *p_fragment_code,
- int p_vertex_code_start,
- int p_fragment_code_start) {
- ERR_FAIL_COND(version);
-
- conditional_version.key = 0;
- new_conditional_version.key = 0;
- uniform_count = p_uniform_count;
- conditional_count = p_conditional_count;
- conditional_defines = p_conditional_defines;
- uniform_names = p_uniform_names;
- vertex_code = p_vertex_code;
- fragment_code = p_fragment_code;
- texunit_pairs = p_texunit_pairs;
- texunit_pair_count = p_texunit_pair_count;
- vertex_code_start = p_vertex_code_start;
- fragment_code_start = p_fragment_code_start;
- attribute_pairs = p_attribute_pairs;
- attribute_pair_count = p_attribute_count;
+ source_code.versions.resize(variant_count);
- {
- String globals_tag = "\nVERTEX_SHADER_GLOBALS";
- String code_tag = "\nVERTEX_SHADER_CODE";
- String code = vertex_code;
- int cpos = code.find(globals_tag);
- if (cpos == -1) {
- vertex_code0 = code.ascii();
- } else {
- vertex_code0 = code.substr(0, cpos).ascii();
- code = code.substr(cpos + globals_tag.length(), code.length());
+ for (int i = 0; i < source_code.versions.size(); i++) {
+ //vertex stage
- cpos = code.find(code_tag);
+ {
+ StringBuilder builder;
+ _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_VERTEX], specialization_default_mask);
- if (cpos == -1) {
- vertex_code1 = code.ascii();
- } else {
- vertex_code1 = code.substr(0, cpos).ascii();
- vertex_code2 = code.substr(cpos + code_tag.length(), code.length()).ascii();
- }
- }
- }
-
- {
- String globals_tag = "\nFRAGMENT_SHADER_GLOBALS";
- String code_tag = "\nFRAGMENT_SHADER_CODE";
- String light_code_tag = "\nLIGHT_SHADER_CODE";
- String code = fragment_code;
- int cpos = code.find(globals_tag);
- if (cpos == -1) {
- fragment_code0 = code.ascii();
- } else {
- fragment_code0 = code.substr(0, cpos).ascii();
- code = code.substr(cpos + globals_tag.length(), code.length());
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "vertex";
+ stage.code = builder.as_string();
- cpos = code.find(light_code_tag);
+ source_code.versions.write[i].stages.push_back(stage);
+ }
- String code2;
+ //fragment stage
+ {
+ StringBuilder builder;
+ _build_variant_code(builder, i, version, stage_templates[STAGE_TYPE_FRAGMENT], specialization_default_mask);
- if (cpos != -1) {
- fragment_code1 = code.substr(0, cpos).ascii();
- code2 = code.substr(cpos + light_code_tag.length(), code.length());
- } else {
- code2 = code;
- }
+ RS::ShaderNativeSourceCode::Version::Stage stage;
+ stage.name = "fragment";
+ stage.code = builder.as_string();
- cpos = code2.find(code_tag);
- if (cpos == -1) {
- fragment_code2 = code2.ascii();
- } else {
- fragment_code2 = code2.substr(0, cpos).ascii();
- fragment_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii();
- }
+ source_code.versions.write[i].stages.push_back(stage);
}
}
- glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units);
-
- valid = true;
+ return source_code;
}
-void ShaderGLES3::finish() {
- const VersionKey *V = NULL;
+String ShaderGLES3::_version_get_sha1(Version *p_version) const {
+ StringBuilder hash_build;
- while ((V = version_map.next(V))) {
- Version &v = version_map[*V];
- glDeleteShader(v.vert_id);
- glDeleteShader(v.frag_id);
- glDeleteProgram(v.id);
+ hash_build.append("[uniforms]");
+ hash_build.append(p_version->uniforms.get_data());
+ hash_build.append("[vertex_globals]");
+ hash_build.append(p_version->vertex_globals.get_data());
+ hash_build.append("[fragment_globals]");
+ hash_build.append(p_version->fragment_globals.get_data());
- if (v.uniform_location)
- memdelete_arr(v.uniform_location);
+ Vector<StringName> code_sections;
+ for (const KeyValue<StringName, CharString> &E : p_version->code_sections) {
+ code_sections.push_back(E.key);
}
-}
-
-void ShaderGLES3::clear_caches() {
- const VersionKey *V = NULL;
+ code_sections.sort_custom<StringName::AlphCompare>();
- while ((V = version_map.next(V))) {
- Version &v = version_map[*V];
- glDeleteShader(v.vert_id);
- glDeleteShader(v.frag_id);
- glDeleteProgram(v.id);
- memdelete_arr(v.uniform_location);
+ for (int i = 0; i < code_sections.size(); i++) {
+ hash_build.append(String("[code:") + String(code_sections[i]) + "]");
+ hash_build.append(p_version->code_sections[code_sections[i]].get_data());
}
-
- version_map.clear();
-
- custom_code_map.clear();
- version = NULL;
- last_custom_code = 1;
- uniforms_dirty = true;
-}
-
-uint32_t ShaderGLES3::create_custom_shader() {
- custom_code_map[last_custom_code] = CustomCode();
- custom_code_map[last_custom_code].version = 1;
- return last_custom_code++;
-}
-
-void ShaderGLES3::set_custom_shader_code(uint32_t p_code_id,
- const String &p_vertex,
- const String &p_vertex_globals,
- const String &p_fragment,
- const String &p_light,
- const String &p_fragment_globals,
- const Vector<StringName> &p_uniforms,
- const Vector<StringName> &p_texture_uniforms,
- const Vector<CharString> &p_custom_defines) {
- CustomCode *cc = custom_code_map.getptr(p_code_id);
- ERR_FAIL_COND(!cc);
-
- cc->vertex = p_vertex;
- cc->vertex_globals = p_vertex_globals;
- cc->fragment = p_fragment;
- cc->fragment_globals = p_fragment_globals;
- cc->light = p_light;
- cc->custom_uniforms = p_uniforms;
- cc->custom_defines = p_custom_defines;
- cc->texture_uniforms = p_texture_uniforms;
- cc->version++;
-}
-
-void ShaderGLES3::set_custom_shader(uint32_t p_code_id) {
- new_conditional_version.code_version = p_code_id;
-}
-
-void ShaderGLES3::free_custom_shader(uint32_t p_code_id) {
- ERR_FAIL_COND(!custom_code_map.has(p_code_id));
- if (conditional_version.code_version == p_code_id) {
- conditional_version.code_version = 0; //do not keep using a version that is going away
- unbind();
+ for (int i = 0; i < p_version->custom_defines.size(); i++) {
+ hash_build.append("[custom_defines:" + itos(i) + "]");
+ hash_build.append(p_version->custom_defines[i].get_data());
}
- VersionKey key;
- key.code_version = p_code_id;
- for (Set<uint32_t>::Element *E = custom_code_map[p_code_id].versions.front(); E; E = E->next()) {
- key.version = E->get();
- ERR_CONTINUE(!version_map.has(key));
- Version &v = version_map[key];
-
- glDeleteShader(v.vert_id);
- glDeleteShader(v.frag_id);
- glDeleteProgram(v.id);
- memdelete_arr(v.uniform_location);
- v.id = 0;
-
- version_map.erase(key);
- }
-
- custom_code_map.erase(p_code_id);
+ return hash_build.as_string().sha1_text();
}
-void ShaderGLES3::use_material(void *p_material) {
- RasterizerStorageGLES3::Material *material = (RasterizerStorageGLES3::Material *)p_material;
+//static const char *shader_file_header = "GLSC";
+//static const uint32_t cache_file_version = 2;
- if (!material) {
- return;
- }
+bool ShaderGLES3::_load_from_cache(Version *p_version) {
+#if 0
+ String sha1 = _version_get_sha1(p_version);
+ String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache";
- if (!material->shader) {
- return;
+ FileAccessRef f = FileAccess::open(path, FileAccess::READ);
+ if (!f) {
+ return false;
}
- Version *v = version_map.getptr(conditional_version);
-
- // bind uniforms
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order >= 0)
- continue; // this is a texture, doesn't go here
-
- Map<StringName, GLint>::Element *L = v->custom_uniform_locations.find(E->key());
- if (!L || L->get() < 0)
- continue; //uniform not valid
-
- GLuint location = L->get();
-
- Map<StringName, Variant>::Element *V = material->params.find(E->key());
-
- if (V) {
- switch (E->get().type) {
- case ShaderLanguage::TYPE_BOOL: {
- bool boolean = V->get();
- glUniform1i(location, boolean ? 1 : 0);
- } break;
-
- case ShaderLanguage::TYPE_BVEC2: {
- int flags = V->get();
- glUniform2i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0);
- } break;
-
- case ShaderLanguage::TYPE_BVEC3: {
- int flags = V->get();
- glUniform3i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0);
-
- } break;
-
- case ShaderLanguage::TYPE_BVEC4: {
- int flags = V->get();
- glUniform4i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0, (flags & 8) ? 1 : 0);
-
- } break;
-
- case ShaderLanguage::TYPE_INT:
- case ShaderLanguage::TYPE_UINT: {
- int value = V->get();
- glUniform1i(location, value);
- } break;
-
- case ShaderLanguage::TYPE_IVEC2:
- case ShaderLanguage::TYPE_UVEC2: {
- Array r = V->get();
- const int count = 2;
- if (r.size() == count) {
- int values[count];
- for (int i = 0; i < count; i++) {
- values[i] = r[i];
- }
- glUniform2i(location, values[0], values[1]);
- }
-
- } break;
-
- case ShaderLanguage::TYPE_IVEC3:
- case ShaderLanguage::TYPE_UVEC3: {
- Array r = V->get();
- const int count = 3;
- if (r.size() == count) {
- int values[count];
- for (int i = 0; i < count; i++) {
- values[i] = r[i];
- }
- glUniform3i(location, values[0], values[1], values[2]);
- }
-
- } break;
-
- case ShaderLanguage::TYPE_IVEC4:
- case ShaderLanguage::TYPE_UVEC4: {
- Array r = V->get();
- const int count = 4;
- if (r.size() == count) {
- int values[count];
- for (int i = 0; i < count; i++) {
- values[i] = r[i];
- }
- glUniform4i(location, values[0], values[1], values[2], values[3]);
- }
-
- } break;
-
- case ShaderLanguage::TYPE_FLOAT: {
- float value = V->get();
- glUniform1f(location, value);
-
- } break;
-
- case ShaderLanguage::TYPE_VEC2: {
- Vector2 value = V->get();
- glUniform2f(location, value.x, value.y);
- } break;
-
- case ShaderLanguage::TYPE_VEC3: {
- Vector3 value = V->get();
- glUniform3f(location, value.x, value.y, value.z);
- } break;
-
- case ShaderLanguage::TYPE_VEC4: {
- if (V->get().get_type() == Variant::COLOR) {
- Color value = V->get();
- glUniform4f(location, value.r, value.g, value.b, value.a);
- } else if (V->get().get_type() == Variant::QUATERNION) {
- Quaternion value = V->get();
- glUniform4f(location, value.x, value.y, value.z, value.w);
- } else {
- Plane value = V->get();
- glUniform4f(location, value.normal.x, value.normal.y, value.normal.z, value.d);
- }
-
- } break;
-
- case ShaderLanguage::TYPE_MAT2: {
- Transform2D tr = V->get();
- GLfloat matrix[4] = {
- /* build a 16x16 matrix */
- (GLfloat)tr.elements[0][0],
- (GLfloat)tr.elements[0][1],
- (GLfloat)tr.elements[1][0],
- (GLfloat)tr.elements[1][1],
- };
- glUniformMatrix2fv(location, 1, GL_FALSE, matrix);
-
- } break;
-
- case ShaderLanguage::TYPE_MAT3: {
- Basis val = V->get();
-
- GLfloat mat[9] = {
- (GLfloat)val.elements[0][0],
- (GLfloat)val.elements[1][0],
- (GLfloat)val.elements[2][0],
- (GLfloat)val.elements[0][1],
- (GLfloat)val.elements[1][1],
- (GLfloat)val.elements[2][1],
- (GLfloat)val.elements[0][2],
- (GLfloat)val.elements[1][2],
- (GLfloat)val.elements[2][2],
- };
-
- glUniformMatrix3fv(location, 1, GL_FALSE, mat);
-
- } break;
-
- case ShaderLanguage::TYPE_MAT4: {
- Transform2D tr = V->get();
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- (GLfloat)tr.elements[0][0],
- (GLfloat)tr.elements[0][1],
- (GLfloat)0,
- (GLfloat)0,
- (GLfloat)tr.elements[1][0],
- (GLfloat)tr.elements[1][1],
- (GLfloat)0,
- (GLfloat)0,
- (GLfloat)0,
- (GLfloat)0,
- (GLfloat)1,
- (GLfloat)0,
- (GLfloat)tr.elements[2][0],
- (GLfloat)tr.elements[2][1],
- (GLfloat)0,
- (GLfloat)1
- };
-
- glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
-
- } break;
-
- default: {
- ERR_PRINT("ShaderNode type missing, bug?");
- } break;
- }
- } else if (E->get().default_value.size()) {
- const Vector<ShaderLanguage::ConstantNode::Value> &values = E->get().default_value;
- switch (E->get().type) {
- case ShaderLanguage::TYPE_BOOL: {
- glUniform1i(location, values[0].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC2: {
- glUniform2i(location, values[0].boolean, values[1].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC3: {
- glUniform3i(location, values[0].boolean, values[1].boolean, values[2].boolean);
- } break;
-
- case ShaderLanguage::TYPE_BVEC4: {
- glUniform4i(location, values[0].boolean, values[1].boolean, values[2].boolean, values[3].boolean);
- } break;
-
- case ShaderLanguage::TYPE_INT: {
- glUniform1i(location, values[0].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC2: {
- glUniform2i(location, values[0].sint, values[1].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC3: {
- glUniform3i(location, values[0].sint, values[1].sint, values[2].sint);
- } break;
-
- case ShaderLanguage::TYPE_IVEC4: {
- glUniform4i(location, values[0].sint, values[1].sint, values[2].sint, values[3].sint);
- } break;
-
- case ShaderLanguage::TYPE_UINT: {
- glUniform1i(location, values[0].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC2: {
- glUniform2i(location, values[0].uint, values[1].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC3: {
- glUniform3i(location, values[0].uint, values[1].uint, values[2].uint);
- } break;
-
- case ShaderLanguage::TYPE_UVEC4: {
- glUniform4i(location, values[0].uint, values[1].uint, values[2].uint, values[3].uint);
- } break;
-
- case ShaderLanguage::TYPE_FLOAT: {
- glUniform1f(location, values[0].real);
- } break;
-
- case ShaderLanguage::TYPE_VEC2: {
- glUniform2f(location, values[0].real, values[1].real);
- } break;
+ char header[5] = { 0, 0, 0, 0, 0 };
+ f->get_buffer((uint8_t *)header, 4);
+ ERR_FAIL_COND_V(header != String(shader_file_header), false);
- case ShaderLanguage::TYPE_VEC3: {
- glUniform3f(location, values[0].real, values[1].real, values[2].real);
- } break;
-
- case ShaderLanguage::TYPE_VEC4: {
- glUniform4f(location, values[0].real, values[1].real, values[2].real, values[3].real);
- } break;
-
- case ShaderLanguage::TYPE_MAT2: {
- GLfloat mat[4];
-
- for (int i = 0; i < 4; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix2fv(location, 1, GL_FALSE, mat);
- } break;
-
- case ShaderLanguage::TYPE_MAT3: {
- GLfloat mat[9];
-
- for (int i = 0; i < 9; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix3fv(location, 1, GL_FALSE, mat);
-
- } break;
-
- case ShaderLanguage::TYPE_MAT4: {
- GLfloat mat[16];
-
- for (int i = 0; i < 16; i++) {
- mat[i] = values[i].real;
- }
-
- glUniformMatrix4fv(location, 1, GL_FALSE, mat);
+ uint32_t file_version = f->get_32();
+ if (file_version != cache_file_version) {
+ return false; // wrong version
+ }
- } break;
+ uint32_t variant_count = f->get_32();
- case ShaderLanguage::TYPE_SAMPLER2D: {
- } break;
+ ERR_FAIL_COND_V(variant_count != (uint32_t)variant_count, false); //should not happen but check
- /*
- case ShaderLanguage::TYPE_SAMPLEREXT: {
- } break;
-*/
- case ShaderLanguage::TYPE_ISAMPLER2D: {
- } break;
+ for (uint32_t i = 0; i < variant_count; i++) {
+ uint32_t variant_size = f->get_32();
+ ERR_FAIL_COND_V(variant_size == 0 && variants_enabled[i], false);
+ if (!variants_enabled[i]) {
+ continue;
+ }
+ Vector<uint8_t> variant_bytes;
+ variant_bytes.resize(variant_size);
- case ShaderLanguage::TYPE_USAMPLER2D: {
- } break;
+ uint32_t br = f->get_buffer(variant_bytes.ptrw(), variant_size);
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
- } break;
+ ERR_FAIL_COND_V(br != variant_size, false);
- case ShaderLanguage::TYPE_SAMPLER2DARRAY:
- case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY:
- case ShaderLanguage::TYPE_SAMPLER3D:
- case ShaderLanguage::TYPE_ISAMPLER3D:
- case ShaderLanguage::TYPE_USAMPLER3D: {
- // Not implemented in OpenGL
- } break;
+ p_version->variant_data[i] = variant_bytes;
+ }
- case ShaderLanguage::TYPE_VOID: {
- // Nothing to do?
- } break;
- default: {
- ERR_PRINT("ShaderNode type missing, bug?");
- } break;
+ for (uint32_t i = 0; i < variant_count; i++) {
+ if (!variants_enabled[i]) {
+ MutexLock lock(variant_set_mutex);
+ p_version->variants[i] = RID();
+ continue;
+ }
+ RID shader = GLES3::get_singleton()->shader_create_from_bytecode(p_version->variant_data[i]);
+ if (shader.is_null()) {
+ for (uint32_t j = 0; j < i; j++) {
+ GLES3::get_singleton()->free(p_version->variants[i]);
}
- } else { //zero
+ ERR_FAIL_COND_V(shader.is_null(), false);
+ }
+ {
+ MutexLock lock(variant_set_mutex);
+ p_version->variants[i] = shader;
+ }
+ }
- switch (E->get().type) {
- case ShaderLanguage::TYPE_BOOL: {
- glUniform1i(location, GL_FALSE);
- } break;
+ memdelete_arr(p_version->variant_data); //clear stages
+ p_version->variant_data = nullptr;
+ p_version->valid = true;
+ return true;
+#endif
+ return false;
+}
- case ShaderLanguage::TYPE_BVEC2: {
- glUniform2i(location, GL_FALSE, GL_FALSE);
- } break;
+void ShaderGLES3::_save_to_cache(Version *p_version) {
+#if 0
+ String sha1 = _version_get_sha1(p_version);
+ String path = shader_cache_dir.plus_file(name).plus_file(base_sha256).plus_file(sha1) + ".cache";
- case ShaderLanguage::TYPE_BVEC3: {
- glUniform3i(location, GL_FALSE, GL_FALSE, GL_FALSE);
- } break;
+ FileAccessRef f = FileAccess::open(path, FileAccess::WRITE);
+ ERR_FAIL_COND(!f);
+ f->store_buffer((const uint8_t *)shader_file_header, 4);
+ f->store_32(cache_file_version); //file version
+ uint32_t variant_count = variant_count;
+ f->store_32(variant_count); //variant count
- case ShaderLanguage::TYPE_BVEC4: {
- glUniform4i(location, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- } break;
+ for (uint32_t i = 0; i < variant_count; i++) {
+ f->store_32(p_version->variant_data[i].size()); //stage count
+ f->store_buffer(p_version->variant_data[i].ptr(), p_version->variant_data[i].size());
+ }
- case ShaderLanguage::TYPE_INT: {
- glUniform1i(location, 0);
- } break;
+ f->close();
+#endif
+}
- case ShaderLanguage::TYPE_IVEC2: {
- glUniform2i(location, 0, 0);
- } break;
+void ShaderGLES3::_clear_version(Version *p_version) {
+ // Variants not compiled yet, just return
+ if (p_version->variants.size() == 0) {
+ return;
+ }
- case ShaderLanguage::TYPE_IVEC3: {
- glUniform3i(location, 0, 0, 0);
- } break;
+ for (int i = 0; i < variant_count; i++) {
+ for (OAHashMap<uint64_t, Version::Specialization>::Iterator it = p_version->variants[i].iter(); it.valid; it = p_version->variants[i].next_iter(it)) {
+ if (it.valid) {
+ glDeleteShader(it.value->vert_id);
+ glDeleteShader(it.value->frag_id);
+ glDeleteProgram(it.value->id);
+ }
+ }
+ }
- case ShaderLanguage::TYPE_IVEC4: {
- glUniform4i(location, 0, 0, 0, 0);
- } break;
+ p_version->variants.clear();
+}
- case ShaderLanguage::TYPE_UINT: {
- glUniform1i(location, 0);
- } break;
+void ShaderGLES3::_initialize_version(Version *p_version) {
+ ERR_FAIL_COND(p_version->variants.size() > 0);
+ p_version->variants.reserve(variant_count);
+ for (int i = 0; i < variant_count; i++) {
+ OAHashMap<uint64_t, Version::Specialization> variant;
+ p_version->variants.push_back(variant);
+ Version::Specialization spec;
+ _compile_specialization(spec, i, p_version, specialization_default_mask);
+ p_version->variants[i].insert(specialization_default_mask, spec);
+ }
+}
- case ShaderLanguage::TYPE_UVEC2: {
- glUniform2i(location, 0, 0);
- } break;
+void ShaderGLES3::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize) {
+ Version *version = version_owner.get_or_null(p_version);
+ ERR_FAIL_COND(!version);
- case ShaderLanguage::TYPE_UVEC3: {
- glUniform3i(location, 0, 0, 0);
- } break;
+ _clear_version(version); //clear if existing
- case ShaderLanguage::TYPE_UVEC4: {
- glUniform4i(location, 0, 0, 0, 0);
- } break;
+ version->vertex_globals = p_vertex_globals.utf8();
+ version->fragment_globals = p_fragment_globals.utf8();
+ version->uniforms = p_uniforms.utf8();
+ version->code_sections.clear();
+ version->texture_uniforms = p_texture_uniforms;
+ for (const KeyValue<String, String> &E : p_code) {
+ version->code_sections[StringName(E.key.to_upper())] = E.value.utf8();
+ }
- case ShaderLanguage::TYPE_FLOAT: {
- glUniform1f(location, 0);
- } break;
+ version->custom_defines.clear();
+ for (int i = 0; i < p_custom_defines.size(); i++) {
+ version->custom_defines.push_back(p_custom_defines[i].utf8());
+ }
- case ShaderLanguage::TYPE_VEC2: {
- glUniform2f(location, 0, 0);
- } break;
+ if (p_initialize) {
+ _initialize_version(version);
+ }
+}
- case ShaderLanguage::TYPE_VEC3: {
- glUniform3f(location, 0, 0, 0);
- } break;
+bool ShaderGLES3::version_is_valid(RID p_version) {
+ Version *version = version_owner.get_or_null(p_version);
+ return version != nullptr;
+}
- case ShaderLanguage::TYPE_VEC4: {
- glUniform4f(location, 0, 0, 0, 0);
- } break;
+bool ShaderGLES3::version_free(RID p_version) {
+ if (version_owner.owns(p_version)) {
+ Version *version = version_owner.get_or_null(p_version);
+ _clear_version(version);
+ version_owner.free(p_version);
+ } else {
+ return false;
+ }
- case ShaderLanguage::TYPE_MAT2: {
- GLfloat mat[4] = { 0, 0, 0, 0 };
+ return true;
+}
- glUniformMatrix2fv(location, 1, GL_FALSE, mat);
- } break;
+bool ShaderGLES3::shader_cache_cleanup_on_start = false;
- case ShaderLanguage::TYPE_MAT3: {
- GLfloat mat[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ShaderGLES3::ShaderGLES3() {
+}
- glUniformMatrix3fv(location, 1, GL_FALSE, mat);
+void ShaderGLES3::initialize(const String &p_general_defines, int p_base_texture_index) {
+ general_defines = p_general_defines.utf8();
+ base_texture_index = p_base_texture_index;
- } break;
+ _init();
- case ShaderLanguage::TYPE_MAT4: {
- GLfloat mat[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ if (shader_cache_dir != String()) {
+ StringBuilder hash_build;
- glUniformMatrix4fv(location, 1, GL_FALSE, mat);
+ hash_build.append("[base_hash]");
+ hash_build.append(base_sha256);
+ hash_build.append("[general_defines]");
+ hash_build.append(general_defines.get_data());
+ for (int i = 0; i < variant_count; i++) {
+ hash_build.append("[variant_defines:" + itos(i) + "]");
+ hash_build.append(variant_defines[i]);
+ }
- } break;
+ base_sha256 = hash_build.as_string().sha256_text();
- case ShaderLanguage::TYPE_SAMPLER2D: {
- } break;
+ DirAccessRef d = DirAccess::open(shader_cache_dir);
+ ERR_FAIL_COND(!d);
+ if (d->change_dir(name) != OK) {
+ Error err = d->make_dir(name);
+ ERR_FAIL_COND(err != OK);
+ d->change_dir(name);
+ }
- /*
- case ShaderLanguage::TYPE_SAMPLEREXT: {
- } break;
-*/
+ //erase other versions?
+ if (shader_cache_cleanup_on_start) {
+ }
+ //
+ if (d->change_dir(base_sha256) != OK) {
+ Error err = d->make_dir(base_sha256);
+ ERR_FAIL_COND(err != OK);
+ }
+ shader_cache_dir_valid = true;
- case ShaderLanguage::TYPE_ISAMPLER2D: {
- } break;
+ print_verbose("Shader '" + name + "' SHA256: " + base_sha256);
+ }
- case ShaderLanguage::TYPE_USAMPLER2D: {
- } break;
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units);
+}
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
- } break;
+void ShaderGLES3::set_shader_cache_dir(const String &p_dir) {
+ shader_cache_dir = p_dir;
+}
- case ShaderLanguage::TYPE_SAMPLER2DARRAY:
- case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
- case ShaderLanguage::TYPE_USAMPLER2DARRAY:
- case ShaderLanguage::TYPE_SAMPLER3D:
- case ShaderLanguage::TYPE_ISAMPLER3D:
- case ShaderLanguage::TYPE_USAMPLER3D: {
- // Not implemented in OpenGL
- } break;
+void ShaderGLES3::set_shader_cache_save_compressed(bool p_enable) {
+ shader_cache_save_compressed = p_enable;
+}
- case ShaderLanguage::TYPE_VOID: {
- // Nothing to do?
- } break;
- default: {
- ERR_PRINT("ShaderNode type missing, bug?");
- } break;
- }
- }
- }
+void ShaderGLES3::set_shader_cache_save_compressed_zstd(bool p_enable) {
+ shader_cache_save_compressed_zstd = p_enable;
}
-ShaderGLES3::ShaderGLES3() {
- version = NULL;
- last_custom_code = 1;
- uniforms_dirty = true;
+void ShaderGLES3::set_shader_cache_save_debug(bool p_enable) {
+ shader_cache_save_debug = p_enable;
}
+String ShaderGLES3::shader_cache_dir;
+bool ShaderGLES3::shader_cache_save_compressed = true;
+bool ShaderGLES3::shader_cache_save_compressed_zstd = true;
+bool ShaderGLES3::shader_cache_save_debug = true;
+
ShaderGLES3::~ShaderGLES3() {
- finish();
+ List<RID> remaining;
+ version_owner.get_owned_list(&remaining);
+ if (remaining.size()) {
+ ERR_PRINT(itos(remaining.size()) + " shaders of type " + name + " were never freed");
+ while (remaining.size()) {
+ version_free(remaining.front()->get());
+ remaining.pop_front();
+ }
+ }
}
-
-#endif // GLES3_BACKEND_ENABLED
+#endif
diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h
index 3b9177b4eb..bc593fb187 100644
--- a/drivers/gles3/shader_gles3.h
+++ b/drivers/gles3/shader_gles3.h
@@ -31,8 +31,16 @@
#ifndef SHADER_OPENGL_H
#define SHADER_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#include "core/os/mutex.h"
+#include "core/string/string_builder.h"
+#include "core/templates/hash_map.h"
+#include "core/templates/local_vector.h"
+#include "core/templates/map.h"
+#include "core/templates/rid_owner.h"
+#include "core/variant/variant.h"
+#include "servers/rendering_server.h"
+
+#ifdef GLES3_ENABLED
// This must come first to avoid windows.h mess
#include "platform_config.h"
@@ -42,236 +50,200 @@
#include OPENGL_INCLUDE_H
#endif
-#include "core/math/camera_matrix.h"
-#include "core/templates/hash_map.h"
-#include "core/templates/map.h"
-#include "core/templates/pair.h"
-#include "core/variant/variant.h"
-#include "servers/rendering/shader_language.h"
-
#include <stdio.h>
-
-class RasterizerStorageGLES3;
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
class ShaderGLES3 {
protected:
- struct Enum {
- uint64_t mask;
- uint64_t shift;
- const char *defines[16];
- };
-
- struct EnumValue {
- uint64_t set_mask;
- uint64_t clear_mask;
- };
-
- struct AttributePair {
+ struct TexUnitPair {
const char *name;
int index;
};
- struct UniformPair {
+ struct UBOPair {
const char *name;
- Variant::Type type_hint;
+ int index;
};
- struct TexUnitPair {
+ struct Specialization {
const char *name;
- int index;
+ bool default_value = false;
};
- bool uniforms_dirty;
-
private:
- bool valid = false;
-
- //@TODO Optimize to a fixed set of shader pools and use a LRU
- int uniform_count;
- int texunit_pair_count;
- int conditional_count;
- int vertex_code_start;
- int fragment_code_start;
- int attribute_pair_count;
-
- struct CustomCode {
- String vertex;
- String vertex_globals;
- String fragment;
- String fragment_globals;
- String light;
- uint32_t version;
- Vector<StringName> texture_uniforms;
- Vector<StringName> custom_uniforms;
- Vector<CharString> custom_defines;
- Set<uint32_t> versions;
- };
+ //versions
+ CharString general_defines;
+ // A version is a high-level construct which is a combination of built-in and user-defined shader code
+ // Variants use #idefs to toggle behaviour on and off to change behaviour of the shader
+ // Specializations use #ifdefs to toggle behaviour on and off for performance, on supporting hardware, they will compile a version with everything enabled, and then compile more copies to improve performance
+ // Use specializations to enable and disabled advanced features, use variants to toggle behaviour when different data may be used (e.g. using a samplerArray vs a sampler)
struct Version {
- GLuint id;
- GLuint vert_id;
- GLuint frag_id;
- GLint *uniform_location;
- Vector<GLint> texture_uniform_locations;
- Map<StringName, GLint> custom_uniform_locations;
- uint32_t code_version;
- bool ok;
- Version() {
- id = 0;
- vert_id = 0;
- frag_id = 0;
- uniform_location = NULL;
- code_version = 0;
- ok = false;
- }
- };
-
- Version *version;
+ Vector<StringName> texture_uniforms;
+ CharString uniforms;
+ CharString vertex_globals;
+ CharString fragment_globals;
+ Map<StringName, CharString> code_sections;
+ Vector<CharString> custom_defines;
- union VersionKey {
- struct {
- uint32_t version;
- uint32_t code_version;
+ struct Specialization {
+ GLuint id;
+ GLuint vert_id;
+ GLuint frag_id;
+ LocalVector<GLint> uniform_location;
+ LocalVector<GLint> texture_uniform_locations;
+ Map<StringName, GLint> custom_uniform_locations;
+ bool build_queued = false;
+ bool ok = false;
+ Specialization() {
+ id = 0;
+ vert_id = 0;
+ frag_id = 0;
+ }
};
- uint64_t key;
- bool operator==(const VersionKey &p_key) const { return key == p_key.key; }
- bool operator<(const VersionKey &p_key) const { return key < p_key.key; }
- };
- struct VersionKeyHash {
- static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); }
+ LocalVector<OAHashMap<uint64_t, Specialization>> variants;
};
- //this should use a way more cachefriendly version..
- HashMap<VersionKey, Version, VersionKeyHash> version_map;
-
- HashMap<uint32_t, CustomCode> custom_code_map;
- uint32_t last_custom_code;
+ Mutex variant_set_mutex;
- VersionKey conditional_version;
- VersionKey new_conditional_version;
+ void _compile_specialization(Version::Specialization &spec, uint32_t p_variant, Version *p_version, uint64_t p_specialization);
- virtual String get_shader_name() const = 0;
+ void _clear_version(Version *p_version);
+ void _initialize_version(Version *p_version);
- const char **conditional_defines;
- const char **uniform_names;
- const AttributePair *attribute_pairs;
- const TexUnitPair *texunit_pairs;
- const char *vertex_code;
- const char *fragment_code;
- CharString fragment_code0;
- CharString fragment_code1;
- CharString fragment_code2;
- CharString fragment_code3;
+ RID_Owner<Version> version_owner;
- CharString vertex_code0;
- CharString vertex_code1;
- CharString vertex_code2;
+ struct StageTemplate {
+ struct Chunk {
+ enum Type {
+ TYPE_MATERIAL_UNIFORMS,
+ TYPE_VERTEX_GLOBALS,
+ TYPE_FRAGMENT_GLOBALS,
+ TYPE_CODE,
+ TYPE_TEXT
+ };
- Vector<CharString> custom_defines;
+ Type type;
+ StringName code;
+ CharString text;
+ };
+ LocalVector<Chunk> chunks;
+ };
- Version *get_current_version();
+ String name;
- static ShaderGLES3 *active;
+ String base_sha256;
- int max_image_units;
+ static String shader_cache_dir;
+ static bool shader_cache_cleanup_on_start;
+ static bool shader_cache_save_compressed;
+ static bool shader_cache_save_compressed_zstd;
+ static bool shader_cache_save_debug;
+ bool shader_cache_dir_valid = false;
- Map<StringName, Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value>>> uniform_values;
+ GLint max_image_units;
-protected:
- _FORCE_INLINE_ int _get_uniform(int p_which) const;
- _FORCE_INLINE_ void _set_conditional(int p_which, bool p_value);
-
- void setup(const char **p_conditional_defines,
- int p_conditional_count,
- const char **p_uniform_names,
- int p_uniform_count,
- const AttributePair *p_attribute_pairs,
- int p_attribute_count,
- const TexUnitPair *p_texunit_pairs,
- int p_texunit_pair_count,
- const char *p_vertex_code,
- const char *p_fragment_code,
- int p_vertex_code_start,
- int p_fragment_code_start);
+ enum StageType {
+ STAGE_TYPE_VERTEX,
+ STAGE_TYPE_FRAGMENT,
+ STAGE_TYPE_MAX,
+ };
- ShaderGLES3();
+ StageTemplate stage_templates[STAGE_TYPE_MAX];
-public:
- enum {
- CUSTOM_SHADER_DISABLED = 0
- };
+ void _build_variant_code(StringBuilder &p_builder, uint32_t p_variant, const Version *p_version, const StageTemplate &p_template, uint64_t p_specialization);
- GLint get_uniform_location(const String &p_name) const;
- GLint get_uniform_location(int p_index) const;
+ void _add_stage(const char *p_code, StageType p_stage_type);
- static _FORCE_INLINE_ ShaderGLES3 *get_active() { return active; }
- bool bind();
- void unbind();
+ String _version_get_sha1(Version *p_version) const;
+ bool _load_from_cache(Version *p_version);
+ void _save_to_cache(Version *p_version);
- inline GLuint get_program() const { return version ? version->id : 0; }
+ const char **uniform_names = nullptr;
+ int uniform_count = 0;
+ const UBOPair *ubo_pairs = nullptr;
+ int ubo_count = 0;
+ const TexUnitPair *texunit_pairs = nullptr;
+ int texunit_pair_count = 0;
+ int specialization_count = 0;
+ const Specialization *specializations = nullptr;
+ uint64_t specialization_default_mask = 0;
+ const char **variant_defines = nullptr;
+ int variant_count = 0;
- void clear_caches();
+ int base_texture_index = 0;
+ Version::Specialization *current_shader = nullptr;
- uint32_t create_custom_shader();
- void set_custom_shader_code(uint32_t p_code_id,
- const String &p_vertex,
- const String &p_vertex_globals,
- const String &p_fragment,
- const String &p_light,
- const String &p_fragment_globals,
- const Vector<StringName> &p_uniforms,
- const Vector<StringName> &p_texture_uniforms,
- const Vector<CharString> &p_custom_defines);
+protected:
+ ShaderGLES3();
+ void _setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_name, int p_uniform_count, const char **p_uniform_names, int p_ubo_count, const UBOPair *p_ubos, int p_texture_count, const TexUnitPair *p_tex_units, int p_specialization_count, const Specialization *p_specializations, int p_variant_count, const char **p_variants);
- void set_custom_shader(uint32_t p_code_id);
- void free_custom_shader(uint32_t p_code_id);
+ _FORCE_INLINE_ void _version_bind_shader(RID p_version, int p_variant, uint64_t p_specialization) {
+ ERR_FAIL_INDEX(p_variant, variant_count);
- uint32_t get_version_key() const { return conditional_version.version; }
+ Version *version = version_owner.get_or_null(p_version);
+ ERR_FAIL_COND(!version);
- // this void* is actually a RasterizerStorageGLES3::Material, but C++ doesn't
- // like forward declared nested classes.
- void use_material(void *p_material);
+ if (version->variants.size() == 0) {
+ _initialize_version(version); //may lack initialization
+ }
- _FORCE_INLINE_ uint32_t get_version() const { return new_conditional_version.version; }
- _FORCE_INLINE_ bool is_version_valid() const { return version && version->ok; }
+ Version::Specialization *spec = version->variants[p_variant].lookup_ptr(p_specialization);
+ if (!spec) {
+ if (false) {
+ // Queue load this specialization and use defaults in the meantime (TODO)
+
+ spec = version->variants[p_variant].lookup_ptr(specialization_default_mask);
+ } else {
+ // Compile on the spot
+ Version::Specialization s;
+ _compile_specialization(s, p_variant, version, p_specialization);
+ version->variants[p_variant].insert(p_specialization, s);
+ spec = version->variants[p_variant].lookup_ptr(p_specialization);
+ }
+ } else if (spec->build_queued) {
+ // Still queued, wait
+ spec = version->variants[p_variant].lookup_ptr(specialization_default_mask);
+ }
- virtual void init() = 0;
- void finish();
+ ERR_FAIL_COND(!spec); // Should never happen
+ ERR_FAIL_COND(!spec->ok); // Should never happen
- void add_custom_define(const String &p_define) {
- custom_defines.push_back(p_define.utf8());
+ glUseProgram(spec->id);
+ current_shader = spec;
}
- void get_custom_defines(Vector<String> *p_defines) {
- for (int i = 0; i < custom_defines.size(); i++) {
- p_defines->push_back(custom_defines[i].get_data());
- }
+ _FORCE_INLINE_ int _version_get_uniform(int p_which, RID p_version, int p_variant, uint64_t p_specialization) {
+ ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
+ Version *version = version_owner.get_or_null(p_version);
+ ERR_FAIL_COND_V(!version, -1);
+ return version->variants[p_variant].lookup_ptr(p_specialization)->uniform_location[p_which];
}
- void remove_custom_define(const String &p_define) {
- custom_defines.erase(p_define.utf8());
- }
+ virtual void _init() = 0;
- virtual ~ShaderGLES3();
-};
+public:
+ RID version_create();
+
+ void version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines, const Vector<StringName> &p_texture_uniforms, bool p_initialize = false);
+
+ bool version_is_valid(RID p_version);
-// called a lot, made inline
+ bool version_free(RID p_version);
-int ShaderGLES3::_get_uniform(int p_which) const {
- ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
- ERR_FAIL_COND_V(!version, -1);
- return version->uniform_location[p_which];
-}
+ static void set_shader_cache_dir(const String &p_dir);
+ static void set_shader_cache_save_compressed(bool p_enable);
+ static void set_shader_cache_save_compressed_zstd(bool p_enable);
+ static void set_shader_cache_save_debug(bool p_enable);
-void ShaderGLES3::_set_conditional(int p_which, bool p_value) {
- ERR_FAIL_INDEX(p_which, conditional_count);
- if (p_value)
- new_conditional_version.version |= (1 << p_which);
- else
- new_conditional_version.version &= ~(1 << p_which);
-}
+ RS::ShaderNativeSourceCode version_get_native_source_code(RID p_version);
-#endif // GLES3_BACKEND_ENABLED
+ void initialize(const String &p_general_defines = "", int p_base_texture_index = 0);
+ virtual ~ShaderGLES3();
+};
#endif // SHADER_OPENGL_H
+#endif
diff --git a/drivers/gles3/shaders/SCsub b/drivers/gles3/shaders/SCsub
index 47d56b9947..2f56b77bdc 100644
--- a/drivers/gles3/shaders/SCsub
+++ b/drivers/gles3/shaders/SCsub
@@ -3,12 +3,5 @@
Import("env")
if "GLES3_GLSL" in env["BUILDERS"]:
- env.GLES3_GLSL("copy.glsl")
env.GLES3_GLSL("canvas.glsl")
- env.GLES3_GLSL("canvas_shadow.glsl")
- env.GLES3_GLSL("scene.glsl")
- env.GLES3_GLSL("cubemap_filter.glsl")
- env.GLES3_GLSL("cube_to_dp.glsl")
- env.GLES3_GLSL("effect_blur.glsl")
- env.GLES3_GLSL("tonemap.glsl")
- env.GLES3_GLSL("lens_distorted.glsl")
+ env.GLES3_GLSL("copy.glsl")
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index f2b141252a..a18c451858 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -1,665 +1,753 @@
/* clang-format off */
-[vertex]
+#[modes]
-#ifdef USE_GLES_OVER_GL
-#define lowp
-#define mediump
-#define highp
-#else
-precision highp float;
-precision highp int;
-#endif
+mode_quad =
+mode_ninepatch = #define USE_NINEPATCH
+mode_primitive = #define USE_PRIMITIVE
+mode_attributes = #define USE_ATTRIBUTES
-uniform highp mat4 projection_matrix;
-/* clang-format on */
+#[specializations]
-uniform highp mat4 modelview_matrix;
-uniform highp mat4 extra_matrix;
-layout(location = 0) in highp vec2 vertex;
+DISABLE_LIGHTING = false
-#ifdef USE_ATTRIB_LIGHT_ANGLE
-// shared with tangent, not used in canvas shader
-layout(location = 2) in highp float light_angle;
-#endif
+#[vertex]
+#ifdef USE_ATTRIBUTES
+layout(location = 0) in vec2 vertex_attrib;
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
-#ifdef USE_ATTRIB_MODULATE
-layout(location = 5) in highp vec4 modulate_attrib;
-#endif
+layout(location = 10) in uvec4 bone_attrib;
+layout(location = 11) in vec4 weight_attrib;
-#ifdef USE_ATTRIB_LARGE_VERTEX
-// shared with skeleton attributes, not used in batched shader
-layout(location = 6) in highp vec2 translate_attrib;
-layout(location = 7) in highp vec4 basis_attrib;
#endif
+/* clang-format on */
+#include "canvas_uniforms_inc.glsl"
+#include "stdlib_inc.glsl"
-#ifdef USE_SKELETON
-layout(location = 6) in highp vec4 bone_indices;
-layout(location = 7) in highp vec4 bone_weights;
-#endif
+uniform sampler2D transforms_texture; //texunit:-1
-#ifdef USE_INSTANCING
+out vec2 uv_interp;
+out vec4 color_interp;
+out vec2 vertex_interp;
+flat out int draw_data_instance;
-layout(location = 8) in highp vec4 instance_xform0;
-layout(location = 9) in highp vec4 instance_xform1;
-layout(location = 10) in highp vec4 instance_xform2;
-layout(location = 11) in highp vec4 instance_color;
+#ifdef USE_NINEPATCH
-#ifdef USE_INSTANCE_CUSTOM
-layout(location = 12) in highp vec4 instance_custom_data;
-#endif
+out vec2 pixel_size_interp;
#endif
-#ifdef USE_SKELETON
-uniform highp sampler2D skeleton_texture; // texunit:-3
-uniform highp ivec2 skeleton_texture_size;
-uniform highp mat4 skeleton_transform;
-uniform highp mat4 skeleton_transform_inverse;
-#endif
+#ifdef MATERIAL_UNIFORMS_USED
+layout(std140) uniform MaterialUniforms{
+//ubo:4
-out vec2 uv_interp;
-out vec4 color_interp;
+#MATERIAL_UNIFORMS
-#ifdef USE_ATTRIB_MODULATE
-// modulate doesn't need interpolating but we need to send it to the fragment shader
-flat out vec4 modulate_interp;
+};
#endif
-#ifdef MODULATE_USED
-uniform vec4 final_modulate;
-#endif
-
-uniform highp vec2 color_texpixel_size;
+#GLOBALS
-#ifdef USE_TEXTURE_RECT
+void main() {
+ vec4 instance_custom = vec4(0.0);
+ draw_data_instance = gl_InstanceID;
+#ifdef USE_PRIMITIVE
-uniform vec4 dst_rect;
-uniform vec4 src_rect;
+ //weird bug,
+ //this works
+ vec2 vertex;
+ vec2 uv;
+ vec4 color;
+
+ if (gl_VertexID == 0) {
+ vertex = draw_data[draw_data_instance].point_a;
+ uv = draw_data[draw_data_instance].uv_a;
+ color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_a_rg), unpackHalf2x16(draw_data[draw_data_instance].color_a_ba));
+ } else if (gl_VertexID == 1) {
+ vertex = draw_data[draw_data_instance].point_b;
+ uv = draw_data[draw_data_instance].uv_b;
+ color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_b_rg), unpackHalf2x16(draw_data[draw_data_instance].color_b_ba));
+ } else {
+ vertex = draw_data[draw_data_instance].point_c;
+ uv = draw_data[draw_data_instance].uv_c;
+ color = vec4(unpackHalf2x16(draw_data[draw_data_instance].color_c_rg), unpackHalf2x16(draw_data[draw_data_instance].color_c_ba));
+ }
+ uvec4 bones = uvec4(0, 0, 0, 0);
+ vec4 bone_weights = vec4(0.0);
-#endif
+#elif defined(USE_ATTRIBUTES)
-uniform highp float time;
-
-#ifdef USE_LIGHTING
-
-// light matrices
-uniform highp mat4 light_matrix;
-uniform highp mat4 light_matrix_inverse;
-uniform highp mat4 light_local_matrix;
-uniform highp mat4 shadow_matrix;
-uniform highp vec4 light_color;
-uniform highp vec4 light_shadow_color;
-uniform highp vec2 light_pos;
-uniform highp float shadowpixel_size;
-uniform highp float shadow_gradient;
-uniform highp float light_height;
-uniform highp float light_outside_alpha;
-uniform highp float shadow_distance_mult;
-
-out vec4 light_uv_interp;
-out vec2 transformed_light_uv;
-out vec4 local_rot;
-
-#ifdef USE_SHADOWS
-out highp vec2 pos;
-#endif
+ vec2 vertex = vertex_attrib;
+ vec4 color = color_attrib * draw_data[draw_data_instance].modulation;
+ vec2 uv = uv_attrib;
-const bool at_light_pass = true;
+ uvec4 bones = bone_attrib;
+ vec4 bone_weights = weight_attrib;
#else
-const bool at_light_pass = false;
-#endif
-/* clang-format off */
+ vec2 vertex_base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ vec2 vertex_base = vertex_base_arr[gl_VertexID];
-VERTEX_SHADER_GLOBALS
+ vec2 uv = draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw) * ((draw_data[draw_data_instance].flags & FLAGS_TRANSPOSE_RECT) != uint(0) ? vertex_base.yx : vertex_base.xy);
+ vec4 color = draw_data[draw_data_instance].modulation;
+ vec2 vertex = draw_data[draw_data_instance].dst_rect.xy + abs(draw_data[draw_data_instance].dst_rect.zw) * mix(vertex_base, vec2(1.0, 1.0) - vertex_base, lessThan(draw_data[draw_data_instance].src_rect.zw, vec2(0.0, 0.0)));
+ uvec4 bones = uvec4(0, 0, 0, 0);
-/* clang-format on */
+#endif
-vec2 select(vec2 a, vec2 b, bvec2 c) {
- vec2 ret;
+ mat4 world_matrix = mat4(vec4(draw_data[draw_data_instance].world_x, 0.0, 0.0), vec4(draw_data[draw_data_instance].world_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(draw_data[draw_data_instance].world_ofs, 0.0, 1.0));
- ret.x = c.x ? b.x : a.x;
- ret.y = c.y ? b.y : a.y;
+ // MultiMeshes don't batch, so always read from draw_data[0]
+ uint instancing = draw_data[0].flags & FLAGS_INSTANCING_MASK;
- return ret;
-}
+#ifdef USE_ATTRIBUTES
+/*
+ if (instancing > 1) {
+ // trails
-void main() {
- vec4 color = color_attrib;
- vec2 uv;
+ uint stride = 2 + 1 + 1; //particles always uses this format
-#ifdef USE_INSTANCING
- mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
- color *= instance_color;
+ uint trail_size = instancing;
-#ifdef USE_INSTANCE_CUSTOM
- vec4 instance_custom = instance_custom_data;
-#else
- vec4 instance_custom = vec4(0.0);
-#endif
+ uint offset = trail_size * stride * gl_InstanceID;
-#else
- mat4 extra_matrix_instance = extra_matrix;
- vec4 instance_custom = vec4(0.0);
-#endif
+ vec4 pcolor;
+ vec2 new_vertex;
+ {
+ uint boffset = offset + bone_attrib.x * stride;
+ new_vertex = (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.x;
+ pcolor = transforms.data[boffset + 2] * weight_attrib.x;
+ }
+ if (weight_attrib.y > 0.001) {
+ uint boffset = offset + bone_attrib.y * stride;
+ new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.y;
+ pcolor += transforms.data[boffset + 2] * weight_attrib.y;
+ }
+ if (weight_attrib.z > 0.001) {
+ uint boffset = offset + bone_attrib.z * stride;
+ new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.z;
+ pcolor += transforms.data[boffset + 2] * weight_attrib.z;
+ }
+ if (weight_attrib.w > 0.001) {
+ uint boffset = offset + bone_attrib.w * stride;
+ new_vertex += (vec4(vertex, 0.0, 1.0) * mat4(transforms.data[boffset + 0], transforms.data[boffset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy * weight_attrib.w;
+ pcolor += transforms.data[boffset + 2] * weight_attrib.w;
+ }
-#ifdef USE_TEXTURE_RECT
+ instance_custom = transforms.data[offset + 3];
- if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
- uv = src_rect.xy + abs(src_rect.zw) * vertex.yx;
- } else {
- uv = src_rect.xy + abs(src_rect.zw) * vertex;
+ vertex = new_vertex;
+ color *= pcolor;
+ } else*/
+#endif // USE_ATTRIBUTES
+/*
+ {
+ if (instancing == 1) {
+ uint stride = 2;
+ {
+ if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) {
+ stride += 1;
+ }
+ if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
+ stride += 1;
+ }
+ }
+
+ uint offset = stride * gl_InstanceID;
+
+ mat4 matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
+ offset += 2;
+
+ if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_COLORS)) {
+ color *= transforms.data[offset];
+ offset += 1;
+ }
+
+ if (bool(draw_data[0].flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
+ instance_custom = transforms.data[offset];
+ }
+
+ matrix = transpose(matrix);
+ world_matrix = world_matrix * matrix;
+ }
+ }
+*/
+#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE)
+ if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_PARTICLES)) {
+ //scale by texture size
+ vertex /= draw_data[draw_data_instance].color_texture_pixel_size;
}
-
- vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
-
- // This is what is done in the GLES 3 bindings and should
- // take care of flipped rects.
- //
- // But it doesn't.
- // I don't know why, will need to investigate further.
-
- outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0)));
-
- // outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex;
-#else
- vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
-
- uv = uv_attrib;
#endif
+#ifdef USE_POINT_SIZE
float point_size = 1.0;
-
+#endif
{
- vec2 src_vtx = outvec.xy;
- /* clang-format off */
-
-VERTEX_SHADER_CODE
-
- /* clang-format on */
+#CODE : VERTEX
}
- gl_PointSize = point_size;
+#ifdef USE_NINEPATCH
+ pixel_size_interp = abs(draw_data[draw_data_instance].dst_rect.zw) * vertex_base;
+#endif
-#ifdef USE_ATTRIB_MODULATE
- // modulate doesn't need interpolating but we need to send it to the fragment shader
- modulate_interp = modulate_attrib;
+#if !defined(SKIP_TRANSFORM_USED)
+ vertex = (world_matrix * vec4(vertex, 0.0, 1.0)).xy;
#endif
-#ifdef USE_ATTRIB_LARGE_VERTEX
- // transform is in attributes
- vec2 temp;
+ color_interp = color;
- temp = outvec.xy;
- temp.x = (outvec.x * basis_attrib.x) + (outvec.y * basis_attrib.z);
- temp.y = (outvec.x * basis_attrib.y) + (outvec.y * basis_attrib.w);
+ if (use_pixel_snap) {
+ vertex = floor(vertex + 0.5);
+ // precision issue on some hardware creates artifacts within texture
+ // offset uv by a small amount to avoid
+ uv += 1e-5;
+ }
- temp += translate_attrib;
- outvec.xy = temp;
+#ifdef USE_ATTRIBUTES
+#if 0
+ if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone
+ //skeleton transform
+ ivec4 bone_indicesi = ivec4(bone_indices);
-#else
+ uvec2 tex_ofs = bone_indicesi.x * 2;
- // transform is in uniforms
-#if !defined(SKIP_TRANSFORM_USED)
- outvec = extra_matrix_instance * outvec;
- outvec = modelview_matrix * outvec;
-#endif
+ mat2x4 m;
+ m = mat2x4(
+ texelFetch(skeleton_buffer, tex_ofs + 0),
+ texelFetch(skeleton_buffer, tex_ofs + 1)) *
+ bone_weights.x;
-#endif // not large integer
+ tex_ofs = bone_indicesi.y * 2;
- color_interp = color;
+ m += mat2x4(
+ texelFetch(skeleton_buffer, tex_ofs + 0),
+ texelFetch(skeleton_buffer, tex_ofs + 1)) *
+ bone_weights.y;
-#ifdef USE_PIXEL_SNAP
- outvec.xy = floor(outvec + 0.5).xy;
- // precision issue on some hardware creates artifacts within texture
- // offset uv by a small amount to avoid
- uv += 1e-5;
-#endif
+ tex_ofs = bone_indicesi.z * 2;
-#ifdef USE_SKELETON
+ m += mat2x4(
+ texelFetch(skeleton_buffer, tex_ofs + 0),
+ texelFetch(skeleton_buffer, tex_ofs + 1)) *
+ bone_weights.z;
- // look up transform from the "pose texture"
- if (bone_weights != vec4(0.0)) {
- highp mat4 bone_transform = mat4(0.0);
+ tex_ofs = bone_indicesi.w * 2;
- for (int i = 0; i < 4; i++) {
- ivec2 tex_ofs = ivec2(int(bone_indices[i]) * 2, 0);
+ m += mat2x4(
+ texelFetch(skeleton_buffer, tex_ofs + 0),
+ texelFetch(skeleton_buffer, tex_ofs + 1)) *
+ bone_weights.w;
- highp mat4 b = mat4(
- texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(0, 0)),
- texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(1, 0)),
- vec4(0.0, 0.0, 1.0, 0.0),
- vec4(0.0, 0.0, 0.0, 1.0));
+ mat4 bone_matrix = skeleton_data.skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_data.skeleton_transform_inverse;
- bone_transform += b * bone_weights[i];
- }
-
- mat4 bone_matrix = skeleton_transform * transpose(bone_transform) * skeleton_transform_inverse;
-
- outvec = bone_matrix * outvec;
+ //outvec = bone_matrix * outvec;
}
-
#endif
+#endif
+
+ vertex = (canvas_transform * vec4(vertex, 0.0, 1.0)).xy;
+ vertex_interp = vertex;
uv_interp = uv;
- gl_Position = projection_matrix * outvec;
-#ifdef USE_LIGHTING
+ gl_Position = screen_transform * vec4(vertex, 0.0, 1.0);
- light_uv_interp.xy = (light_matrix * outvec).xy;
- light_uv_interp.zw = (light_local_matrix * outvec).xy;
+#ifdef USE_POINT_SIZE
+ gl_PointSize = point_size;
+#endif
+}
- transformed_light_uv = (mat3(light_matrix_inverse) * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping
+#[fragment]
-#ifdef USE_SHADOWS
- pos = outvec.xy;
-#endif
+#include "canvas_uniforms_inc.glsl"
+#include "stdlib_inc.glsl"
-#ifdef USE_ATTRIB_LIGHT_ANGLE
- // we add a fixed offset because we are using the sign later,
- // and don't want floating point error around 0.0
- float la = abs(light_angle) - 1.0;
-
- // vector light angle
- vec4 vla;
- vla.xy = vec2(cos(la), sin(la));
- vla.zw = vec2(-vla.y, vla.x);
-
- // vertical flip encoded in the sign
- vla.zw *= sign(light_angle);
-
- // apply the transform matrix.
- // The rotate will be encoded in the transform matrix for single rects,
- // and just the flips in the light angle.
- // For batching we will encode the rotation and the flips
- // in the light angle, and can use the same shader.
- local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.xy, 0.0, 0.0))).xy);
- local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(vla.zw, 0.0, 0.0))).xy);
-#else
- local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(1.0, 0.0, 0.0, 0.0))).xy);
- local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(0.0, 1.0, 0.0, 0.0))).xy);
-#ifdef USE_TEXTURE_RECT
- local_rot.xy *= sign(src_rect.z);
- local_rot.zw *= sign(src_rect.w);
-#endif
-#endif // not using light angle
+uniform sampler2D atlas_texture; //texunit:-2
+uniform sampler2D shadow_atlas_texture; //texunit:-3
+uniform sampler2D screen_texture; //texunit:-4
+uniform sampler2D sdf_texture; //texunit:-5
+uniform sampler2D normal_texture; //texunit:-6
+uniform sampler2D specular_texture; //texunit:-7
-#endif
-}
+uniform sampler2D color_texture; //texunit:0
-/* clang-format off */
-[fragment]
+in vec2 uv_interp;
+in vec4 color_interp;
+in vec2 vertex_interp;
+flat in int draw_data_instance;
+
+#ifdef USE_NINEPATCH
+
+in vec2 pixel_size_interp;
-#ifdef USE_GLES_OVER_GL
-#define lowp
-#define mediump
-#define highp
-#else
-#if defined(USE_HIGHP_PRECISION)
-precision highp float;
-precision highp int;
-#else
-precision mediump float;
-precision mediump int;
-#endif
#endif
-uniform sampler2D color_texture; // texunit:-1
-/* clang-format on */
-uniform highp vec2 color_texpixel_size;
-uniform mediump sampler2D normal_texture; // texunit:-2
+layout(location = 0) out vec4 frag_color;
+
+#ifdef MATERIAL_UNIFORMS_USED
+uniform MaterialUniforms{
+//ubo:4
-in mediump vec2 uv_interp;
-in mediump vec4 color_interp;
+#MATERIAL_UNIFORMS
-#ifdef USE_ATTRIB_MODULATE
-in mediump vec4 modulate_interp;
+};
#endif
-uniform highp float time;
+vec2 screen_uv_to_sdf(vec2 p_uv) {
+ return screen_to_sdf * p_uv;
+}
-uniform vec4 final_modulate;
+float texture_sdf(vec2 p_sdf) {
+ vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw;
+ float d = texture(sdf_texture, uv).r;
+ d *= SDF_MAX_LENGTH;
+ return d * tex_to_sdf;
+}
-#ifdef SCREEN_TEXTURE_USED
+vec2 texture_sdf_normal(vec2 p_sdf) {
+ vec2 uv = p_sdf * sdf_to_tex.xy + sdf_to_tex.zw;
-uniform sampler2D screen_texture; // texunit:-4
+ const float EPSILON = 0.001;
+ return normalize(vec2(
+ texture(sdf_texture, uv + vec2(EPSILON, 0.0)).r - texture(sdf_texture, uv - vec2(EPSILON, 0.0)).r,
+ texture(sdf_texture, uv + vec2(0.0, EPSILON)).r - texture(sdf_texture, uv - vec2(0.0, EPSILON)).r));
+}
-#endif
+vec2 sdf_to_screen_uv(vec2 p_sdf) {
+ return p_sdf * sdf_to_screen;
+}
-#ifdef SCREEN_UV_USED
+#GLOBALS
-uniform vec2 screen_pixel_size;
+#ifdef LIGHT_CODE_USED
-#endif
+vec4 light_compute(
+ vec3 light_vertex,
+ vec3 light_position,
+ vec3 normal,
+ vec4 light_color,
+ float light_energy,
+ vec4 specular_shininess,
+ inout vec4 shadow_modulate,
+ vec2 screen_uv,
+ vec2 uv,
+ vec4 color, bool is_directional) {
+ vec4 light = vec4(0.0);
-#ifdef USE_LIGHTING
+#CODE : LIGHT
-uniform highp mat4 light_matrix;
-uniform highp mat4 light_local_matrix;
-uniform highp mat4 shadow_matrix;
-uniform highp vec4 light_color;
-uniform highp vec4 light_shadow_color;
-uniform highp vec2 light_pos;
-uniform highp float shadowpixel_size;
-uniform highp float shadow_gradient;
-uniform highp float light_height;
-uniform highp float light_outside_alpha;
-uniform highp float shadow_distance_mult;
+ return light;
+}
-uniform lowp sampler2D light_texture; // texunit:-6
-in vec4 light_uv_interp;
-in vec2 transformed_light_uv;
+#endif
-in vec4 local_rot;
+#ifdef USE_NINEPATCH
-#ifdef USE_SHADOWS
+float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) {
+ float tex_size = 1.0 / tex_pixel_size;
-uniform highp sampler2D shadow_texture; // texunit:-5
-in highp vec2 pos;
+ if (pixel < margin_begin) {
+ return pixel * tex_pixel_size;
+ } else if (pixel >= draw_size - margin_end) {
+ return (tex_size - (draw_size - pixel)) * tex_pixel_size;
+ } else {
+ if (!bool(draw_data[draw_data_instance].flags & FLAGS_NINEPACH_DRAW_CENTER)) {
+ draw_center--;
+ }
-#endif
+ // np_repeat is passed as uniform using NinePatchRect::AxisStretchMode enum.
+ if (np_repeat == 0) { // Stretch.
+ // Convert to ratio.
+ float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end);
+ // Scale to source texture.
+ return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size;
+ } else if (np_repeat == 1) { // Tile.
+ // Convert to offset.
+ float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end);
+ // Scale to source texture.
+ return (margin_begin + ofs) * tex_pixel_size;
+ } else if (np_repeat == 2) { // Tile Fit.
+ // Calculate scale.
+ float src_area = draw_size - margin_begin - margin_end;
+ float dst_area = tex_size - margin_begin - margin_end;
+ float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5));
+ // Convert to ratio.
+ float ratio = (pixel - margin_begin) / src_area;
+ ratio = mod(ratio * scale, 1.0);
+ // Scale to source texture.
+ return (margin_begin + ratio * dst_area) * tex_pixel_size;
+ } else { // Shouldn't happen, but silences compiler warning.
+ return 0.0;
+ }
+ }
+}
-const bool at_light_pass = true;
-#else
-const bool at_light_pass = false;
#endif
-uniform bool use_default_normal;
+vec3 light_normal_compute(vec3 light_vec, vec3 normal, vec3 base_color, vec3 light_color, vec4 specular_shininess, bool specular_shininess_used) {
+ float cNdotL = max(0.0, dot(normal, light_vec));
-layout(location = 0) out mediump vec4 frag_color;
+ if (specular_shininess_used) {
+ //blinn
+ vec3 view = vec3(0.0, 0.0, 1.0); // not great but good enough
+ vec3 half_vec = normalize(view + light_vec);
-/* clang-format off */
+ float cNdotV = max(dot(normal, view), 0.0);
+ float cNdotH = max(dot(normal, half_vec), 0.0);
+ float cVdotH = max(dot(view, half_vec), 0.0);
+ float cLdotH = max(dot(light_vec, half_vec), 0.0);
+ float shininess = exp2(15.0 * specular_shininess.a + 1.0) * 0.25;
+ float blinn = pow(cNdotH, shininess);
+ blinn *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
+ float s = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
-FRAGMENT_SHADER_GLOBALS
+ return specular_shininess.rgb * light_color * s + light_color * base_color * cNdotL;
+ } else {
+ return light_color * base_color * cNdotL;
+ }
+}
-/* clang-format on */
+//float distance = length(shadow_pos);
+vec4 light_shadow_compute(uint light_base, vec4 light_color, vec4 shadow_uv
+#ifdef LIGHT_CODE_USED
+ ,
+ vec3 shadow_modulate
+#endif
+) {
+ float shadow;
+ uint shadow_mode = light_data[light_base].flags & LIGHT_FLAGS_FILTER_MASK;
+
+ if (shadow_mode == LIGHT_FLAGS_SHADOW_NEAREST) {
+ shadow = textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
+ } else if (shadow_mode == LIGHT_FLAGS_SHADOW_PCF5) {
+ vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
+ shadow = 0.0;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
+ shadow /= 5.0;
+ } else { //PCF13
+ vec4 shadow_pixel_size = vec4(light_data[light_base].shadow_pixel_size, 0.0, 0.0, 0.0);
+ shadow = 0.0;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 6.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 5.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 4.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 3.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv - shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 2.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 3.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 4.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 5.0, 0.0).x;
+ shadow += textureProjLod(shadow_atlas_texture, shadow_uv + shadow_pixel_size * 6.0, 0.0).x;
+ shadow /= 13.0;
+ }
-void light_compute(
- inout vec4 light,
- inout vec2 light_vec,
- inout float light_height,
- inout vec4 light_color,
- vec2 light_uv,
- inout vec4 shadow_color,
- inout vec2 shadow_vec,
- vec3 normal,
- vec2 uv,
-#if defined(SCREEN_UV_USED)
- vec2 screen_uv,
+ vec4 shadow_color = unpackUnorm4x8(light_data[light_base].shadow_color);
+#ifdef LIGHT_CODE_USED
+ shadow_color.rgb *= shadow_modulate;
#endif
- vec4 color) {
-#if defined(USE_LIGHT_SHADER_CODE)
+ shadow_color.a *= light_color.a; //respect light alpha
- /* clang-format off */
+ return mix(light_color, shadow_color, shadow);
+}
-LIGHT_SHADER_CODE
+void light_blend_compute(uint light_base, vec4 light_color, inout vec3 color) {
+ uint blend_mode = light_data[light_base].flags & LIGHT_FLAGS_BLEND_MASK;
+
+ switch (blend_mode) {
+ case LIGHT_FLAGS_BLEND_MODE_ADD: {
+ color.rgb += light_color.rgb * light_color.a;
+ } break;
+ case LIGHT_FLAGS_BLEND_MODE_SUB: {
+ color.rgb -= light_color.rgb * light_color.a;
+ } break;
+ case LIGHT_FLAGS_BLEND_MODE_MIX: {
+ color.rgb = mix(color.rgb, light_color.rgb, light_color.a);
+ } break;
+ }
+}
- /* clang-format on */
+float msdf_median(float r, float g, float b, float a) {
+ return min(max(min(r, g), min(max(r, g), b)), a);
+}
-#endif
+vec2 msdf_map(vec2 value, vec2 in_min, vec2 in_max, vec2 out_min, vec2 out_max) {
+ return out_min + (out_max - out_min) * (value - in_min) / (in_max - in_min);
}
void main() {
vec4 color = color_interp;
vec2 uv = uv_interp;
-#ifdef USE_FORCE_REPEAT
- //needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that don't support it
- uv = mod(uv, vec2(1.0, 1.0));
+ vec2 vertex = vertex_interp;
+
+#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE)
+
+#ifdef USE_NINEPATCH
+
+ int draw_center = 2;
+ uv = vec2(
+ map_ninepatch_axis(pixel_size_interp.x, abs(draw_data[draw_data_instance].dst_rect.z), draw_data[draw_data_instance].color_texture_pixel_size.x, draw_data[draw_data_instance].ninepatch_margins.x, draw_data[draw_data_instance].ninepatch_margins.z, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_H_MODE_SHIFT) & 0x3, draw_center),
+ map_ninepatch_axis(pixel_size_interp.y, abs(draw_data[draw_data_instance].dst_rect.w), draw_data[draw_data_instance].color_texture_pixel_size.y, draw_data[draw_data_instance].ninepatch_margins.y, draw_data[draw_data_instance].ninepatch_margins.w, int(draw_data[draw_data_instance].flags >> FLAGS_NINEPATCH_V_MODE_SHIFT) & 0x3, draw_center));
+
+ if (draw_center == 0) {
+ color.a = 0.0;
+ }
+
+ uv = uv * draw_data[draw_data_instance].src_rect.zw + draw_data[draw_data_instance].src_rect.xy; //apply region if needed
+
#endif
+ if (bool(draw_data[draw_data_instance].flags & FLAGS_CLIP_RECT_UV)) {
+ uv = clamp(uv, draw_data[draw_data_instance].src_rect.xy, draw_data[draw_data_instance].src_rect.xy + abs(draw_data[draw_data_instance].src_rect.zw));
+ }
-#if !defined(COLOR_USED)
- //default behavior, texture by color
- color *= texture(color_texture, uv);
#endif
-#ifdef SCREEN_UV_USED
- vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
+#ifndef USE_PRIMITIVE
+ if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_MSDF)) {
+ float px_range = draw_data[draw_data_instance].ninepatch_margins.x;
+ float outline_thickness = draw_data[draw_data_instance].ninepatch_margins.y;
+ //float reserved1 = draw_data[draw_data_instance].ninepatch_margins.z;
+ //float reserved2 = draw_data[draw_data_instance].ninepatch_margins.w;
+
+ vec4 msdf_sample = texture(color_texture, uv);
+ vec2 msdf_size = vec2(textureSize(color_texture, 0));
+ vec2 dest_size = vec2(1.0) / fwidth(uv);
+ float px_size = max(0.5 * dot((vec2(px_range) / msdf_size), dest_size), 1.0);
+ float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b, msdf_sample.a) - 0.5;
+
+ if (outline_thickness > 0) {
+ float cr = clamp(outline_thickness, 0.0, px_range / 2) / px_range;
+ float a = clamp((d + cr) * px_size, 0.0, 1.0);
+ color.a = a * color.a;
+ } else {
+ float a = clamp(d * px_size + 0.5, 0.0, 1.0);
+ color.a = a * color.a;
+ }
+
+ } else {
+#else
+ {
#endif
+ color *= texture(color_texture, uv);
+ }
+
+ uint light_count = (draw_data[draw_data_instance].flags >> FLAGS_LIGHT_COUNT_SHIFT) & uint(0xF); //max 16 lights
+ bool using_light = light_count > uint(0) || directional_light_count > uint(0);
vec3 normal;
#if defined(NORMAL_USED)
-
bool normal_used = true;
#else
bool normal_used = false;
#endif
- if (use_default_normal) {
- normal.xy = texture(normal_texture, uv).xy * 2.0 - 1.0;
+ if (normal_used || (using_light && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) {
+ normal.xy = texture(normal_texture, uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0);
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used = true;
} else {
normal = vec3(0.0, 0.0, 1.0);
}
- {
- float normal_depth = 1.0;
-
-#if defined(NORMALMAP_USED)
- vec3 normal_map = vec3(0.0, 0.0, 1.0);
- normal_used = true;
-#endif
-
- /* clang-format off */
+ vec4 specular_shininess;
-FRAGMENT_SHADER_CODE
+#if defined(SPECULAR_SHININESS_USED)
- /* clang-format on */
-
-#if defined(NORMALMAP_USED)
- normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
-#endif
- }
-
-#ifdef USE_ATTRIB_MODULATE
- color *= modulate_interp;
+ bool specular_shininess_used = true;
#else
-#if !defined(MODULATE_USED)
- color *= final_modulate;
-#endif
+ bool specular_shininess_used = false;
#endif
-#ifdef USE_LIGHTING
-
- vec2 light_vec = transformed_light_uv;
- vec2 shadow_vec = transformed_light_uv;
-
- if (normal_used) {
- normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
+ if (specular_shininess_used || (using_light && normal_used && bool(draw_data[draw_data_instance].flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) {
+ specular_shininess = texture(specular_texture, uv);
+ specular_shininess *= unpackUnorm4x8(draw_data[draw_data_instance].specular_shininess);
+ specular_shininess_used = true;
+ } else {
+ specular_shininess = vec4(1.0);
}
- float att = 1.0;
-
- vec2 light_uv = light_uv_interp.xy;
- vec4 light = texture(light_texture, light_uv);
-
- if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) {
- color.a *= light_outside_alpha; //invisible
-
- } else {
- float real_light_height = light_height;
- vec4 real_light_color = light_color;
- vec4 real_light_shadow_color = light_shadow_color;
-
-#if defined(USE_LIGHT_SHADER_CODE)
- //light is written by the light shader
- light_compute(
- light,
- light_vec,
- real_light_height,
- real_light_color,
- light_uv,
- real_light_shadow_color,
- shadow_vec,
- normal,
- uv,
#if defined(SCREEN_UV_USED)
- screen_uv,
-#endif
- color);
+ vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
+#else
+ vec2 screen_uv = vec2(0.0);
#endif
- light *= real_light_color;
-
- if (normal_used) {
- vec3 light_normal = normalize(vec3(light_vec, -real_light_height));
- light *= max(dot(-light_normal, normal), 0.0);
- }
+ vec3 light_vertex = vec3(vertex, 0.0);
+ vec2 shadow_vertex = vertex;
- color *= light;
-
-#ifdef USE_SHADOWS
+ {
+ float normal_map_depth = 1.0;
-#ifdef SHADOW_VEC_USED
- mat3 inverse_light_matrix = mat3(light_matrix);
- inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
- inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
- inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
- shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy;
-#else
- shadow_vec = light_uv_interp.zw;
+#if defined(NORMAL_MAP_USED)
+ vec3 normal_map = vec3(0.0, 0.0, 1.0);
+ normal_used = true;
#endif
- float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
- float PI = 3.14159265358979323846264;
- /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
- float ang*/
-
- float su, sz;
-
- float abs_angle = abs(angle_to_light);
- vec2 point;
- float sh;
- if (abs_angle < 45.0 * PI / 180.0) {
- point = shadow_vec;
- sh = 0.0 + (1.0 / 8.0);
- } else if (abs_angle > 135.0 * PI / 180.0) {
- point = -shadow_vec;
- sh = 0.5 + (1.0 / 8.0);
- } else if (angle_to_light > 0.0) {
- point = vec2(shadow_vec.y, -shadow_vec.x);
- sh = 0.25 + (1.0 / 8.0);
- } else {
- point = vec2(-shadow_vec.y, shadow_vec.x);
- sh = 0.75 + (1.0 / 8.0);
- }
+#CODE : FRAGMENT
- highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0);
- s.xyz /= s.w;
- su = s.x * 0.5 + 0.5;
- sz = s.z * 0.5 + 0.5;
- //sz=lightlength(light_vec);
+#if defined(NORMAL_MAP_USED)
+ normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_map_depth);
+#endif
+ }
- highp float shadow_attenuation = 0.0;
+ if (normal_used) {
+ //convert by item transform
+ normal.xy = mat2(normalize(draw_data[draw_data_instance].world_x), normalize(draw_data[draw_data_instance].world_y)) * normal.xy;
+ //convert by canvas transform
+ normal = normalize((canvas_normal_transform * vec4(normal, 0.0)).xyz);
+ }
-#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_tex, m_uv) dot(texture((m_tex), (m_uv)), vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0))
+ vec3 base_color = color.rgb;
+ if (bool(draw_data[draw_data_instance].flags & FLAGS_USING_LIGHT_MASK)) {
+ color = vec4(0.0); //invisible by default due to using light mask
+ }
+#ifdef MODE_LIGHT_ONLY
+ color = vec4(0.0);
#else
+ color *= canvas_modulation;
+#endif
-#define SHADOW_DEPTH(m_tex, m_uv) (texture((m_tex), (m_uv)).r)
+#if !defined(DISABLE_LIGHTING) && !defined(MODE_UNSHADED)
-#endif
+ for (uint i = uint(0); i < directional_light_count; i++) {
+ uint light_base = i;
-#ifdef SHADOW_USE_GRADIENT
+ vec2 direction = light_data[light_base].position;
+ vec4 light_color = light_data[light_base].color;
- /* clang-format off */
- /* GLSL es 100 doesn't support line continuation characters(backslashes) */
-#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); }
+#ifdef LIGHT_CODE_USED
+ vec4 shadow_modulate = vec4(1.0);
+ light_color = light_compute(light_vertex, vec3(direction, light_data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true);
#else
-#define SHADOW_TEST(m_ofs) { highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); shadow_attenuation += step(sz, sd); }
- /* clang-format on */
-
+ if (normal_used) {
+ vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_data[light_base].height));
+ light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used);
+ }
#endif
-#ifdef SHADOW_FILTER_NEAREST
+ if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
+ vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
- SHADOW_TEST(su);
+ vec4 shadow_uv = vec4(shadow_pos.x, light_data[light_base].shadow_y_ofs, shadow_pos.y * light_data[light_base].shadow_zfar_inv, 1.0);
+ light_color = light_shadow_compute(light_base, light_color, shadow_uv
+#ifdef LIGHT_CODE_USED
+ ,
+ shadow_modulate.rgb
#endif
+ );
+ }
-#ifdef SHADOW_FILTER_PCF3
-
- SHADOW_TEST(su + shadowpixel_size);
- SHADOW_TEST(su);
- SHADOW_TEST(su - shadowpixel_size);
- shadow_attenuation /= 3.0;
+ light_blend_compute(light_base, light_color, color.rgb);
+ }
-#endif
+ // Positional Lights
-#ifdef SHADOW_FILTER_PCF5
+ for (uint i = uint(0); i < MAX_LIGHTS_PER_ITEM; i++) {
+ if (i >= light_count) {
+ break;
+ }
+ uint light_base;
+ if (i < uint(8)) {
+ if (i < uint(4)) {
+ light_base = draw_data[draw_data_instance].lights.x;
+ } else {
+ light_base = draw_data[draw_data_instance].lights.y;
+ }
+ } else {
+ if (i < uint(12)) {
+ light_base = draw_data[draw_data_instance].lights.z;
+ } else {
+ light_base = draw_data[draw_data_instance].lights.w;
+ }
+ }
+ light_base >>= (i & uint(3)) * uint(8);
+ light_base &= uint(0xFF);
- SHADOW_TEST(su + shadowpixel_size * 2.0);
- SHADOW_TEST(su + shadowpixel_size);
- SHADOW_TEST(su);
- SHADOW_TEST(su - shadowpixel_size);
- SHADOW_TEST(su - shadowpixel_size * 2.0);
- shadow_attenuation /= 5.0;
+ vec2 tex_uv = (vec4(vertex, 0.0, 1.0) * mat4(light_data[light_base].texture_matrix[0], light_data[light_base].texture_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
+ vec2 tex_uv_atlas = tex_uv * light_data[light_base].atlas_rect.zw + light_data[light_base].atlas_rect.xy;
+ vec4 light_color = textureLod(atlas_texture, tex_uv_atlas, 0.0);
+ vec4 light_base_color = light_data[light_base].color;
-#endif
+#ifdef LIGHT_CODE_USED
-#ifdef SHADOW_FILTER_PCF7
+ vec4 shadow_modulate = vec4(1.0);
+ vec3 light_position = vec3(light_data[light_base].position, light_data[light_base].height);
- SHADOW_TEST(su + shadowpixel_size * 3.0);
- SHADOW_TEST(su + shadowpixel_size * 2.0);
- SHADOW_TEST(su + shadowpixel_size);
- SHADOW_TEST(su);
- SHADOW_TEST(su - shadowpixel_size);
- SHADOW_TEST(su - shadowpixel_size * 2.0);
- SHADOW_TEST(su - shadowpixel_size * 3.0);
- shadow_attenuation /= 7.0;
-
-#endif
+ light_color.rgb *= light_base_color.rgb;
+ light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false);
+#else
-#ifdef SHADOW_FILTER_PCF9
+ light_color.rgb *= light_base_color.rgb * light_base_color.a;
- SHADOW_TEST(su + shadowpixel_size * 4.0);
- SHADOW_TEST(su + shadowpixel_size * 3.0);
- SHADOW_TEST(su + shadowpixel_size * 2.0);
- SHADOW_TEST(su + shadowpixel_size);
- SHADOW_TEST(su);
- SHADOW_TEST(su - shadowpixel_size);
- SHADOW_TEST(su - shadowpixel_size * 2.0);
- SHADOW_TEST(su - shadowpixel_size * 3.0);
- SHADOW_TEST(su - shadowpixel_size * 4.0);
- shadow_attenuation /= 9.0;
+ if (normal_used) {
+ vec3 light_pos = vec3(light_data[light_base].position, light_data[light_base].height);
+ vec3 pos = light_vertex;
+ vec3 light_vec = normalize(light_pos - pos);
+ float cNdotL = max(0.0, dot(normal, light_vec));
+ light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used);
+ }
#endif
+ if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) {
+ //if outside the light texture, light color is zero
+ light_color.a = 0.0;
+ }
-#ifdef SHADOW_FILTER_PCF13
-
- SHADOW_TEST(su + shadowpixel_size * 6.0);
- SHADOW_TEST(su + shadowpixel_size * 5.0);
- SHADOW_TEST(su + shadowpixel_size * 4.0);
- SHADOW_TEST(su + shadowpixel_size * 3.0);
- SHADOW_TEST(su + shadowpixel_size * 2.0);
- SHADOW_TEST(su + shadowpixel_size);
- SHADOW_TEST(su);
- SHADOW_TEST(su - shadowpixel_size);
- SHADOW_TEST(su - shadowpixel_size * 2.0);
- SHADOW_TEST(su - shadowpixel_size * 3.0);
- SHADOW_TEST(su - shadowpixel_size * 4.0);
- SHADOW_TEST(su - shadowpixel_size * 5.0);
- SHADOW_TEST(su - shadowpixel_size * 6.0);
- shadow_attenuation /= 13.0;
-
-#endif
+ if (bool(light_data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
+ vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_data[light_base].shadow_matrix[0], light_data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
+
+ vec2 pos_norm = normalize(shadow_pos);
+ vec2 pos_abs = abs(pos_norm);
+ vec2 pos_box = pos_norm / max(pos_abs.x, pos_abs.y);
+ vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476, -0.7071067811865476), vec2(0.7071067811865476, 0.7071067811865476)); //is there a faster way to 45 degrees rot?
+ float tex_ofs;
+ float distance;
+ if (pos_rot.y > 0) {
+ if (pos_rot.x > 0) {
+ tex_ofs = pos_box.y * 0.125 + 0.125;
+ distance = shadow_pos.x;
+ } else {
+ tex_ofs = pos_box.x * -0.125 + (0.25 + 0.125);
+ distance = shadow_pos.y;
+ }
+ } else {
+ if (pos_rot.x < 0) {
+ tex_ofs = pos_box.y * -0.125 + (0.5 + 0.125);
+ distance = -shadow_pos.x;
+ } else {
+ tex_ofs = pos_box.x * 0.125 + (0.75 + 0.125);
+ distance = -shadow_pos.y;
+ }
+ }
+
+ distance *= light_data[light_base].shadow_zfar_inv;
+
+ //float distance = length(shadow_pos);
+ vec4 shadow_uv = vec4(tex_ofs, light_data[light_base].shadow_y_ofs, distance, 1.0);
+
+ light_color = light_shadow_compute(light_base, light_color, shadow_uv
+#ifdef LIGHT_CODE_USED
+ ,
+ shadow_modulate.rgb
+#endif
+ );
+ }
- //color *= shadow_attenuation;
- color = mix(real_light_shadow_color, color, shadow_attenuation);
-//use shadows
-#endif
+ light_blend_compute(light_base, light_color, color.rgb);
}
-
-//use lighting
-#endif
+#endif // UNSHADED
frag_color = color;
}
diff --git a/drivers/gles3/shaders/canvas_shadow.glsl b/drivers/gles3/shaders/canvas_shadow.glsl
index 2b3be43f6e..65389c211a 100644
--- a/drivers/gles3/shaders/canvas_shadow.glsl
+++ b/drivers/gles3/shaders/canvas_shadow.glsl
@@ -10,7 +10,7 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) highp vec3 vertex;
+layout(location = 0) in highp vec3 vertex;
uniform highp mat4 projection_matrix;
/* clang-format on */
diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
new file mode 100644
index 0000000000..e08a15e59d
--- /dev/null
+++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
@@ -0,0 +1,120 @@
+
+#define MAX_LIGHTS_PER_ITEM uint(16)
+
+#define M_PI 3.14159265359
+
+#define SDF_MAX_LENGTH 16384.0
+
+//1 means enabled, 2+ means trails in use
+#define FLAGS_INSTANCING_MASK uint(0x7F)
+#define FLAGS_INSTANCING_HAS_COLORS uint(1 << 7)
+#define FLAGS_INSTANCING_HAS_CUSTOM_DATA uint(1 << 8)
+
+#define FLAGS_CLIP_RECT_UV uint(1 << 9)
+#define FLAGS_TRANSPOSE_RECT uint(1 << 10)
+#define FLAGS_USING_LIGHT_MASK uint(1 << 11)
+#define FLAGS_NINEPACH_DRAW_CENTER uint(1 << 12)
+#define FLAGS_USING_PARTICLES uint(1 << 13)
+
+#define FLAGS_NINEPATCH_H_MODE_SHIFT 16
+#define FLAGS_NINEPATCH_V_MODE_SHIFT 18
+
+#define FLAGS_LIGHT_COUNT_SHIFT 20
+
+#define FLAGS_DEFAULT_NORMAL_MAP_USED uint(1 << 26)
+#define FLAGS_DEFAULT_SPECULAR_MAP_USED uint(1 << 27)
+
+#define FLAGS_USE_MSDF uint(1 << 28)
+
+// must be always 128 bytes long
+struct DrawData {
+ vec2 world_x;
+ vec2 world_y;
+ vec2 world_ofs;
+ vec2 color_texture_pixel_size;
+#ifdef USE_PRIMITIVE
+ vec2 point_a;
+ vec2 point_b;
+ vec2 point_c;
+ vec2 uv_a;
+ vec2 uv_b;
+ vec2 uv_c;
+ uint color_a_rg;
+ uint color_a_ba;
+ uint color_b_rg;
+ uint color_b_ba;
+ uint color_c_rg;
+ uint color_c_ba;
+#else
+ vec4 modulation;
+ vec4 ninepatch_margins;
+ vec4 dst_rect; //for built-in rect and UV
+ vec4 src_rect;
+ uint pad;
+ uint pad2;
+#endif
+ uint flags;
+ uint specular_shininess;
+ uvec4 lights;
+};
+
+layout(std140) uniform GlobalVariableData { //ubo:1
+ vec4 global_variables[MAX_GLOBAL_VARIABLES];
+};
+
+layout(std140) uniform CanvasData { //ubo:0
+ mat4 canvas_transform;
+ mat4 screen_transform;
+ mat4 canvas_normal_transform;
+ vec4 canvas_modulation;
+ vec2 screen_pixel_size;
+ float time;
+ bool use_pixel_snap;
+
+ vec4 sdf_to_tex;
+ vec2 screen_to_sdf;
+ vec2 sdf_to_screen;
+
+ uint directional_light_count;
+ float tex_to_sdf;
+ uint pad1;
+ uint pad2;
+};
+
+#define LIGHT_FLAGS_BLEND_MASK uint(3 << 16)
+#define LIGHT_FLAGS_BLEND_MODE_ADD uint(0 << 16)
+#define LIGHT_FLAGS_BLEND_MODE_SUB uint(1 << 16)
+#define LIGHT_FLAGS_BLEND_MODE_MIX uint(2 << 16)
+#define LIGHT_FLAGS_BLEND_MODE_MASK uint(3 << 16)
+#define LIGHT_FLAGS_HAS_SHADOW uint(1 << 20)
+#define LIGHT_FLAGS_FILTER_SHIFT 22
+#define LIGHT_FLAGS_FILTER_MASK uint(3 << 22)
+#define LIGHT_FLAGS_SHADOW_NEAREST uint(0 << 22)
+#define LIGHT_FLAGS_SHADOW_PCF5 uint(1 << 22)
+#define LIGHT_FLAGS_SHADOW_PCF13 uint(2 << 22)
+
+struct Light {
+ mat2x4 texture_matrix; //light to texture coordinate matrix (transposed)
+ mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed)
+ vec4 color;
+
+ uint shadow_color; // packed
+ uint flags; //index to light texture
+ float shadow_pixel_size;
+ float height;
+
+ vec2 position;
+ float shadow_zfar_inv;
+ float shadow_y_ofs;
+
+ vec4 atlas_rect;
+};
+
+layout(std140) uniform LightData { //ubo:2
+ Light light_data[MAX_LIGHTS];
+};
+
+layout(std140) uniform DrawDataInstances { //ubo:3
+
+ DrawData draw_data[MAX_DRAW_DATA_INSTANCES];
+};
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index 598c6fd614..62332a15a7 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -1,5 +1,21 @@
/* clang-format off */
-[vertex]
+#[modes]
+
+mode_default =
+mode_cubemap = #define USE_CUBEMAP
+mode_panorama = #define USE_PANORAMA
+mode_copy_section = #define USE_COPY_SECTION
+mode_asym_pano = #define USE_ASYM_PANO
+mode_no_alpha = #define USE_NO_ALPHA
+mode_custom_alpha = #define USE_CUSTOM_ALPHA
+mode_multiplier = #define USE_MULTIPLIER
+mode_sep_cbcr_texture = #define USE_SEP_CBCR_TEXTURE
+mode_ycbcr_to_rgb = #define USE_YCBCR_TO_RGB
+
+#[specializations]
+
+
+#[vertex]
#ifdef USE_GLES_OVER_GL
#define lowp
@@ -10,16 +26,16 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) highp vec4 vertex_attrib;
+layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
-layout(location = 4) vec3 cube_in;
+layout(location = 4) in vec3 cube_in;
#else
-layout(location = 4) vec2 uv_in;
+layout(location = 4) in vec2 uv_in;
#endif
-layout(location = 5) vec2 uv2_in;
+layout(location = 5) in vec2 uv2_in;
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
out vec3 cube_interp;
@@ -28,11 +44,6 @@ out vec2 uv_interp;
#endif
out vec2 uv2_interp;
-// These definitions are here because the shader-wrapper builder does
-// not understand `#elif defined()`
-#ifdef USE_DISPLAY_TRANSFORM
-#endif
-
#ifdef USE_COPY_SECTION
uniform highp vec4 copy_section;
#elif defined(USE_DISPLAY_TRANSFORM)
@@ -60,7 +71,7 @@ void main() {
}
/* clang-format off */
-[fragment]
+#[fragment]
#define M_PI 3.14159265359
@@ -96,7 +107,7 @@ uniform samplerCube source_cube; // texunit:0
uniform sampler2D source; // texunit:0
#endif
-#ifdef SEP_CBCR_TEXTURE
+#ifdef USE_SEP_CBCR_TEXTURE
uniform sampler2D CbCr; //texunit:1
#endif
@@ -156,8 +167,8 @@ void main() {
vec4 color = texturePanorama(source, normalize(cube_normal.xyz));
#elif defined(USE_CUBEMAP)
- vec4 color = textureCube(source_cube, normalize(cube_interp));
-#elif defined(SEP_CBCR_TEXTURE)
+ vec4 color = texture(source_cube, normalize(cube_interp));
+#elif defined(USE_SEP_CBCR_TEXTURE)
vec4 color;
color.r = texture(source, uv_interp).r;
color.gb = texture(CbCr, uv_interp).rg - vec2(0.5, 0.5);
@@ -166,7 +177,7 @@ void main() {
vec4 color = texture(source, uv_interp);
#endif
-#ifdef YCBCR_TO_RGB
+#ifdef USE_YCBCR_TO_RGB
// YCbCr -> RGB conversion
// Using BT.601, which is the standard for SDTV is provided as a reference
diff --git a/drivers/gles3/shaders/cube_to_dp.glsl b/drivers/gles3/shaders/cube_to_dp.glsl
index ea4df79d4e..2384529a89 100644
--- a/drivers/gles3/shaders/cube_to_dp.glsl
+++ b/drivers/gles3/shaders/cube_to_dp.glsl
@@ -10,9 +10,9 @@ precision mediump float;
precision mediump int;
#endif
-layout(location = 0) highp vec4 vertex_attrib;
+layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
-layout(location = 4) vec2 uv_in;
+layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 04bf3ebf02..2081abfef6 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) highp vec2 vertex;
+layout(location = 0) in highp vec2 vertex;
/* clang-format on */
-layout(location = 4) highp vec2 uv;
+layout(location = 4) in highp vec2 uv;
out highp vec2 uv_interp;
diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl
index 80063a7175..c9184cca77 100644
--- a/drivers/gles3/shaders/effect_blur.glsl
+++ b/drivers/gles3/shaders/effect_blur.glsl
@@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) vec2 vertex_attrib;
+layout(location = 0) in vec2 vertex_attrib;
/* clang-format on */
-layout(location = 4) vec2 uv_in;
+layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
diff --git a/drivers/gles3/shaders/lens_distorted.glsl b/drivers/gles3/shaders/lens_distorted.glsl
index 64c2d70cc8..3aaf1050e5 100644
--- a/drivers/gles3/shaders/lens_distorted.glsl
+++ b/drivers/gles3/shaders/lens_distorted.glsl
@@ -10,7 +10,7 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) highp vec2 vertex;
+layout(location = 0) in highp vec2 vertex;
/* clang-format on */
uniform vec2 offset;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index c2f3908395..98c92a1d99 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -18,38 +18,38 @@ precision highp int;
// attributes
//
-layout(location = 0) highp vec4 vertex_attrib;
+layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
-layout(location = 1) vec3 normal_attrib;
+layout(location = 1) in vec3 normal_attrib;
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
-layout(location = 2) vec4 tangent_attrib;
+layout(location = 2) in vec4 tangent_attrib;
#endif
#if defined(ENABLE_COLOR_INTERP)
-layout(location = 3) vec4 color_attrib;
+layout(location = 3) in vec4 color_attrib;
#endif
#if defined(ENABLE_UV_INTERP)
-layout(location = 4) vec2 uv_attrib;
+layout(location = 4) in vec2 uv_attrib;
#endif
#if defined(ENABLE_UV2_INTERP) || defined(USE_LIGHTMAP)
-layout(location = 5) vec2 uv2_attrib;
+layout(location = 5) in vec2 uv2_attrib;
#endif
#ifdef USE_SKELETON
#ifdef USE_SKELETON_SOFTWARE
-layout(location = 13) highp vec4 bone_transform_row_0;
-layout(location = 14) highp vec4 bone_transform_row_1;
-layout(location = 15) highp vec4 bone_transform_row_2;
+layout(location = 13) in highp vec4 bone_transform_row_0;
+layout(location = 14) in highp vec4 bone_transform_row_1;
+layout(location = 15) in highp vec4 bone_transform_row_2;
#else
-layout(location = 6) vec4 bone_ids;
-layout(location = 7) highp vec4 bone_weights;
+layout(location = 6) in vec4 bone_ids;
+layout(location = 7) in highp vec4 bone_weights;
uniform highp sampler2D bone_transforms; // texunit:-1
uniform ivec2 skeleton_texture_size;
@@ -60,12 +60,12 @@ uniform ivec2 skeleton_texture_size;
#ifdef USE_INSTANCING
-layout(location = 8) highp vec4 instance_xform_row_0;
-layout(location = 9) highp vec4 instance_xform_row_1;
-layout(location = 10) highp vec4 instance_xform_row_2;
+layout(location = 8) in highp vec4 instance_xform_row_0;
+layout(location = 9) in highp vec4 instance_xform_row_1;
+layout(location = 10) in highp vec4 instance_xform_row_2;
-layout(location = 11) highp vec4 instance_color;
-layout(location = 12) highp vec4 instance_custom_data;
+layout(location = 11) in highp vec4 instance_color;
+layout(location = 12) in highp vec4 instance_custom_data;
#endif
diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl
new file mode 100644
index 0000000000..2eddf9d479
--- /dev/null
+++ b/drivers/gles3/shaders/stdlib_inc.glsl
@@ -0,0 +1,58 @@
+//TODO: only needed by GLES_OVER_GL
+
+uint float2half(uint f) {
+ return ((f >> uint(16)) & uint(0x8000)) |
+ ((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
+ ((f >> uint(13)) & uint(0x03ff));
+}
+
+uint half2float(uint h) {
+ return ((h & uint(0x8000)) << uint(16)) | (((h & uint(0x7c00)) + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13));
+}
+
+uint packHalf2x16(vec2 v) {
+ return float2half(floatBitsToUint(v.x)) | float2half(floatBitsToUint(v.y)) << uint(16);
+}
+
+vec2 unpackHalf2x16(uint v) {
+ return vec2(uintBitsToFloat(half2float(v & uint(0xffff))),
+ uintBitsToFloat(half2float(v >> uint(16))));
+}
+
+uint packUnorm2x16(vec2 v) {
+ uvec2 uv = uvec2(round(clamp(v, vec2(0.0), vec2(1.0)) * 65535.0));
+ return uv.x | uv.y << uint(16);
+}
+
+vec2 unpackUnorm2x16(uint p) {
+ return vec2(float(p & uint(0xffff)), float(p >> uint(16))) * 0.000015259021; // 1.0 / 65535.0 optimization
+}
+
+uint packSnorm2x16(vec2 v) {
+ uvec2 uv = uvec2(round(clamp(v, vec2(-1.0), vec2(1.0)) * 32767.0) + 32767.0);
+ return uv.x | uv.y << uint(16);
+}
+
+vec2 unpackSnorm2x16(uint p) {
+ vec2 v = vec2(float(p & uint(0xffff)), float(p >> uint(16)));
+ return clamp((v - 32767.0) * vec2(0.00003051851), vec2(-1.0), vec2(1.0));
+}
+
+uint packUnorm4x8(vec4 v) {
+ uvec4 uv = uvec4(round(clamp(v, vec4(0.0), vec4(1.0)) * 255.0));
+ return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24);
+}
+
+vec4 unpackUnorm4x8(uint p) {
+ return vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24))) * 0.00392156862; // 1.0 / 255.0
+}
+
+uint packSnorm4x8(vec4 v) {
+ uvec4 uv = uvec4(round(clamp(v, vec4(-1.0), vec4(1.0)) * 127.0) + 127.0);
+ return uv.x | uv.y << uint(8) | uv.z << uint(16) | uv.w << uint(24);
+}
+
+vec4 unpackSnorm4x8(uint p) {
+ vec4 v = vec4(float(p & uint(0xffff)), float((p >> uint(8)) & uint(0xffff)), float((p >> uint(16)) & uint(0xffff)), float(p >> uint(24)));
+ return clamp((v - vec4(127.0)) * vec4(0.00787401574), vec4(-1.0), vec4(1.0));
+}
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 8b3aa4d309..4f962626a3 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -10,9 +10,9 @@ precision highp float;
precision highp int;
#endif
-layout(location = 0) vec2 vertex_attrib;
+layout(location = 0) in vec2 vertex_attrib;
/* clang-format on */
-layout(location = 4) vec2 uv_in;
+layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp
index f4ae6decab..ca52eaeacb 100644
--- a/drivers/gles3/texture_loader_gles3.cpp
+++ b/drivers/gles3/texture_loader_gles3.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "texture_loader_gles3.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "core/io/file_access.h"
#include "core/string/print_string.h"
diff --git a/drivers/gles3/texture_loader_gles3.h b/drivers/gles3/texture_loader_gles3.h
index 68540fc5c0..54ddf80a96 100644
--- a/drivers/gles3/texture_loader_gles3.h
+++ b/drivers/gles3/texture_loader_gles3.h
@@ -31,8 +31,7 @@
#ifndef TEXTURE_LOADER_OPENGL_H
#define TEXTURE_LOADER_OPENGL_H
-#include "drivers/gles3/rasterizer_platforms.h"
-#ifdef GLES3_BACKEND_ENABLED
+#ifdef GLES3_ENABLED
#include "core/io/resource_loader.h"
#include "scene/resources/texture.h"
@@ -47,6 +46,6 @@ public:
virtual ~ResourceFormatGLES2Texture() {}
};
-#endif // GLES3_BACKEND_ENABLED
+#endif // GLES3_ENABLED
#endif // TEXTURE_LOADER_OPENGL_H
diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h
index ccd279e694..78d37074e5 100644
--- a/drivers/windows/dir_access_windows.h
+++ b/drivers/windows/dir_access_windows.h
@@ -35,10 +35,6 @@
#include "core/io/dir_access.h"
-/**
- @author Juan Linietsky <reduz@gmail.com>
-*/
-
struct DirAccessWindowsPrivate;
class DirAccessWindows : public DirAccess {
@@ -90,6 +86,6 @@ public:
~DirAccessWindows();
};
-#endif //WINDOWS_ENABLED
+#endif // WINDOWS_ENABLED
-#endif
+#endif // DIR_ACCESS_WINDOWS_H
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index eabe0a95e2..96d9ab1064 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -760,12 +760,26 @@ void ActionMapEditor::_add_action_pressed() {
_add_action(add_edit->get_text());
}
+bool ActionMapEditor::_has_action(const String &p_name) const {
+ for (const ActionInfo &action_info : actions_cache) {
+ if (p_name == action_info.name) {
+ return true;
+ }
+ }
+ return false;
+}
+
void ActionMapEditor::_add_action(const String &p_name) {
if (p_name.is_empty() || !_is_action_name_valid(p_name)) {
show_message(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'"));
return;
}
+ if (_has_action(p_name)) {
+ show_message(vformat(TTR("An action with the name '%s' already exists."), p_name));
+ return;
+ }
+
add_edit->clear();
emit_signal(SNAME("action_added"), p_name);
}
@@ -791,6 +805,12 @@ void ActionMapEditor::_action_edited() {
return;
}
+ if (_has_action(new_name)) {
+ ti->set_text(0, old_name);
+ show_message(vformat(TTR("An action with the name '%s' already exists."), new_name));
+ return;
+ }
+
emit_signal(SNAME("action_renamed"), old_name, new_name);
} else if (action_tree->get_selected_column() == 1) {
// Deadzone Edited
diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h
index cf2d871469..e61d1a334a 100644
--- a/editor/action_map_editor.h
+++ b/editor/action_map_editor.h
@@ -168,6 +168,7 @@ private:
void _event_config_confirmed();
void _add_action_pressed();
+ bool _has_action(const String &p_name) const;
void _add_action(const String &p_name);
void _action_edited();
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index a6d2225bdc..058e59dea3 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -145,20 +145,19 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int
}
for (int i = 0; i < color_samples.size() - 1; i++) {
- Vector<Vector2> points;
- Vector<Color> colors;
-
- points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from));
- colors.push_back(color_samples[i]);
-
- points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from));
- colors.push_back(color_samples[i + 1]);
-
- points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from + fh));
- colors.push_back(color_samples[i + 1]);
-
- points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from + fh));
- colors.push_back(color_samples[i]);
+ Vector<Vector2> points = {
+ Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from),
+ Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from),
+ Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from + fh),
+ Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from + fh)
+ };
+
+ Vector<Color> colors = {
+ color_samples[i],
+ color_samples[i + 1],
+ color_samples[i + 1],
+ color_samples[i]
+ };
draw_primitive(points, colors, Vector<Vector2>());
}
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 2759c6cfde..8bad2d9b5b 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -28,10 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
-@author Juan Linietsky <reduzio@gmail.com>
-*/
-
#ifndef CONNECTIONS_DIALOG_H
#define CONNECTIONS_DIALOG_H
@@ -232,4 +228,4 @@ public:
~ConnectionsDock();
};
-#endif
+#endif // CONNECTIONS_DIALOG_H
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index addb168e5f..ddcd32c16f 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -270,5 +270,11 @@ void EditorDebuggerInspector::clear_stack_variables() {
}
String EditorDebuggerInspector::get_stack_variable(const String &p_var) {
- return variables->get_variant(p_var);
+ for (Map<StringName, Variant>::Element *E = variables->prop_values.front(); E; E = E->next()) {
+ String v = E->key().operator String();
+ if (v.get_slice("/", 1) == p_var) {
+ return variables->get_variant(v);
+ }
+ }
+ return String();
}
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index 8e9b2a9368..d5e825a26c 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -645,7 +645,7 @@ EditorProfiler::EditorProfiler() {
variables->connect("item_edited", callable_mp(this, &EditorProfiler::_item_edited));
graph = memnew(TextureRect);
- graph->set_expand(true);
+ graph->set_ignore_texture_size(true);
graph->set_mouse_filter(MOUSE_FILTER_STOP);
graph->connect("draw", callable_mp(this, &EditorProfiler::_graph_tex_draw));
graph->connect("gui_input", callable_mp(this, &EditorProfiler::_graph_tex_input));
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index 42b52a3b38..3cb5d3513d 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -786,7 +786,7 @@ EditorVisualProfiler::EditorVisualProfiler() {
variables->connect("cell_selected", callable_mp(this, &EditorVisualProfiler::_item_selected));
graph = memnew(TextureRect);
- graph->set_expand(true);
+ graph->set_ignore_texture_size(true);
graph->set_mouse_filter(MOUSE_FILTER_STOP);
//graph->set_ignore_mouse(false);
graph->connect("draw", callable_mp(this, &EditorVisualProfiler::_graph_tex_draw));
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index afd5407f37..a8cb2e791c 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2780,8 +2780,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
+ case RUN_USER_DATA_FOLDER: {
+ // ensure_user_data_dir() to prevent the edge case: "Open User 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;
@@ -6038,6 +6038,9 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
+ EDITOR_DEF("interface/editors/sub_editor_panning_scheme", 0);
+ // Should be in sync with ControlScheme in ViewPanner.
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/editors/sub_editor_panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans", PROPERTY_USAGE_DEFAULT));
const Vector<String> textfile_ext = ((String)(EditorSettings::get_singleton()->get("docks/filesystem/textfile_extensions"))).split(",", false);
for (const String &E : textfile_ext) {
@@ -6443,7 +6446,7 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/export", TTR("Export..."), Key::NONE, TTR("Export")), FILE_EXPORT_PROJECT);
p->add_item(TTR("Install Android Build Template..."), FILE_INSTALL_ANDROID_SOURCE);
- p->add_item(TTR("Open Project Data Folder"), RUN_PROJECT_DATA_FOLDER);
+ p->add_item(TTR("Open User Data Folder"), RUN_USER_DATA_FOLDER);
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->connect("plugin_ready", callable_mp(this, &EditorNode::_on_plugin_ready));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 7ecdb7c263..af7223ffb4 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -167,7 +167,7 @@ private:
RUN_PLAY_SCENE,
RUN_PLAY_CUSTOM_SCENE,
RUN_SETTINGS,
- RUN_PROJECT_DATA_FOLDER,
+ RUN_USER_DATA_FOLDER,
RUN_RELOAD_CURRENT_PROJECT,
RUN_PROJECT_MANAGER,
RUN_VCS_METADATA,
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index c649162d7e..6002bcfadc 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -874,7 +874,7 @@ EditorResourcePicker::EditorResourcePicker() {
assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input));
preview_rect = memnew(TextureRect);
- preview_rect->set_expand(true);
+ preview_rect->set_ignore_texture_size(true);
preview_rect->set_anchors_and_offsets_preset(PRESET_WIDE);
preview_rect->set_offset(SIDE_TOP, 1);
preview_rect->set_offset(SIDE_BOTTOM, -1);
diff --git a/editor/import/dynamicfont_import_settings.cpp b/editor/import/dynamicfont_import_settings.cpp
index c8d8cd8ee1..3151496bec 100644
--- a/editor/import/dynamicfont_import_settings.cpp
+++ b/editor/import/dynamicfont_import_settings.cpp
@@ -1185,6 +1185,38 @@ void DynamicFontImportSettings::_lang_remove(Object *p_item, int p_column, int p
memdelete(lang_item);
}
+void DynamicFontImportSettings::_ot_add() {
+ menu_ot->set_position(ot_list->get_screen_transform().xform(ot_list->get_local_mouse_position()));
+ menu_ot->set_size(Vector2(1, 1));
+ menu_ot->popup();
+}
+
+void DynamicFontImportSettings::_ot_add_item(int p_option) {
+ String name = TS->tag_to_name(p_option);
+ for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
+ if (ot_item->get_text(0) == name) {
+ return;
+ }
+ }
+ TreeItem *ot_item = ot_list->create_item(ot_list_root);
+ ERR_FAIL_NULL(ot_item);
+
+ ot_item->set_text(0, name);
+ ot_item->set_editable(0, false);
+ ot_item->set_text(1, "1");
+ ot_item->set_editable(1, true);
+ ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
+ ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+}
+
+void DynamicFontImportSettings::_ot_remove(Object *p_item, int p_column, int p_id) {
+ TreeItem *ot_item = (TreeItem *)p_item;
+ ERR_FAIL_NULL(ot_item);
+
+ ot_list_root->remove_child(ot_item);
+ memdelete(ot_item);
+}
+
void DynamicFontImportSettings::_script_add() {
menu_scripts->set_position(script_list->get_screen_position() + script_list->get_local_mouse_position());
menu_scripts->reset_size();
@@ -1230,6 +1262,7 @@ void DynamicFontImportSettings::_notification(int p_what) {
add_lang->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
add_script->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
add_var->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
+ add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
}
}
@@ -1317,6 +1350,14 @@ void DynamicFontImportSettings::_re_import() {
main_settings["preload/glyph_ranges"] = ranges;
}
+ Dictionary ot_ov;
+ for (TreeItem *ot_item = ot_list_root->get_first_child(); ot_item; ot_item = ot_item->get_next()) {
+ String tag = ot_item->get_text(0);
+ int32_t value = ot_item->get_text(1).to_int();
+ ot_ov[tag] = value;
+ }
+ main_settings["opentype_feature_overrides"] = ot_ov;
+
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("Import settings:");
for (Map<StringName, Variant>::Element *E = main_settings.front(); E; E = E->next()) {
@@ -1373,6 +1414,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
vars_list->clear();
lang_list->clear();
script_list->clear();
+ ot_list->clear();
selected_chars.clear();
selected_glyphs.clear();
@@ -1381,6 +1423,7 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
vars_list_root = vars_list->create_item();
lang_list_root = lang_list->create_item();
script_list_root = script_list->create_item();
+ ot_list_root = ot_list->create_item();
options_variations.clear();
Dictionary var_list = dfont_main->get_supported_variation_list();
@@ -1546,6 +1589,23 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
script_item->set_editable(1, true);
script_item->add_button(2, lang_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
}
+ } else if (key == "opentype_feature_overrides") {
+ Dictionary features = config->get_value("params", key);
+ for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
+ TreeItem *ot_item = ot_list->create_item(ot_list_root);
+ ERR_FAIL_NULL(ot_item);
+ int32_t value = features[*ftr];
+ if (ftr->get_type() == Variant::STRING) {
+ ot_item->set_text(0, *ftr);
+ } else {
+ ot_item->set_text(0, TS->tag_to_name(*ftr));
+ }
+ ot_item->set_editable(0, false);
+ ot_item->set_text(1, itos(value));
+ ot_item->set_editable(1, true);
+ ot_item->add_button(2, ot_list->get_theme_icon("Remove", "EditorIcons"), BUTTON_REMOVE_VAR, false, TTR("Remove"));
+ ot_item->set_button_color(2, 0, Color(1, 1, 1, 0.75));
+ }
} else {
Variant value = config->get_value("params", key);
import_settings_data->defaults[key] = value;
@@ -1570,6 +1630,39 @@ void DynamicFontImportSettings::open_settings(const String &p_path) {
font_preview_label->add_theme_font_override("font", font_preview);
font_preview_label->update();
+ menu_ot->clear();
+ menu_ot_ss->clear();
+ menu_ot_cv->clear();
+ menu_ot_cu->clear();
+ bool have_ss = false;
+ bool have_cv = false;
+ bool have_cu = false;
+ Dictionary features = font_preview->get_feature_list();
+ for (const Variant *ftr = features.next(nullptr); ftr != nullptr; ftr = features.next(ftr)) {
+ String ftr_name = TS->tag_to_name(*ftr);
+ if (ftr_name.begins_with("stylistic_set_")) {
+ menu_ot_ss->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ have_ss = true;
+ } else if (ftr_name.begins_with("character_variant_")) {
+ menu_ot_cv->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ have_cv = true;
+ } else if (ftr_name.begins_with("custom_")) {
+ menu_ot_cu->add_item(ftr_name.replace("custom_", ""), (int32_t)*ftr);
+ have_cu = true;
+ } else {
+ menu_ot->add_item(ftr_name.capitalize(), (int32_t)*ftr);
+ }
+ }
+ if (have_ss) {
+ menu_ot->add_submenu_item(RTR("Stylistic Sets"), "SSMenu");
+ }
+ if (have_cv) {
+ menu_ot->add_submenu_item(RTR("Character Variants"), "CVMenu");
+ }
+ if (have_cu) {
+ menu_ot->add_submenu_item(RTR("Custom"), "CUMenu");
+ }
+
_variations_validate();
popup_centered_ratio();
@@ -1619,6 +1712,25 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
add_child(menu_scripts);
menu_scripts->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_script_add_item));
+ menu_ot = memnew(PopupMenu);
+ add_child(menu_ot);
+ menu_ot->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_cv = memnew(PopupMenu);
+ menu_ot_cv->set_name("CVMenu");
+ menu_ot->add_child(menu_ot_cv);
+ menu_ot_cv->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_ss = memnew(PopupMenu);
+ menu_ot_ss->set_name("SSMenu");
+ menu_ot->add_child(menu_ot_ss);
+ menu_ot_ss->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
+ menu_ot_cu = memnew(PopupMenu);
+ menu_ot_cu->set_name("CUMenu");
+ menu_ot->add_child(menu_ot_cu);
+ menu_ot_cu->connect("id_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add_item));
+
Color warn_color = (EditorNode::get_singleton()) ? EditorNode::get_singleton()->get_gui_base()->get_theme_color("warning_color", "Editor") : Color(1, 1, 0);
// Root layout
@@ -1897,6 +2009,34 @@ DynamicFontImportSettings::DynamicFontImportSettings() {
script_list->connect("button_pressed", callable_mp(this, &DynamicFontImportSettings::_script_remove));
script_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ HBoxContainer *hb_ot = memnew(HBoxContainer);
+ page5_vb->add_child(hb_ot);
+
+ label_ot = memnew(Label);
+ label_ot->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+ label_ot->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ label_ot->set_text(TTR("OpenType feature overrides"));
+ hb_ot->add_child(label_ot);
+
+ add_ot = memnew(Button);
+ hb_ot->add_child(add_ot);
+ add_ot->set_tooltip(TTR("Add feature override"));
+ add_ot->set_icon(add_var->get_theme_icon("Add", "EditorIcons"));
+ add_ot->connect("pressed", callable_mp(this, &DynamicFontImportSettings::_ot_add));
+
+ ot_list = memnew(Tree);
+ page5_vb->add_child(ot_list);
+ ot_list->set_hide_root(true);
+ ot_list->set_columns(3);
+ ot_list->set_column_expand(0, true);
+ ot_list->set_column_custom_minimum_width(0, 80 * EDSCALE);
+ ot_list->set_column_expand(1, true);
+ ot_list->set_column_custom_minimum_width(1, 80 * EDSCALE);
+ ot_list->set_column_expand(2, false);
+ ot_list->set_column_custom_minimum_width(2, 50 * EDSCALE);
+ ot_list->connect("button_pressed", callable_mp(this, &DynamicFontImportSettings::_ot_remove));
+ ot_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+
// Common
import_settings_data.instantiate();
diff --git a/editor/import/dynamicfont_import_settings.h b/editor/import/dynamicfont_import_settings.h
index be8cf7ad3d..89665ae476 100644
--- a/editor/import/dynamicfont_import_settings.h
+++ b/editor/import/dynamicfont_import_settings.h
@@ -120,18 +120,27 @@ class DynamicFontImportSettings : public ConfirmationDialog {
Label *page5_description = nullptr;
Button *add_lang = nullptr;
Button *add_script = nullptr;
+ Button *add_ot = nullptr;
PopupMenu *menu_langs = nullptr;
PopupMenu *menu_scripts = nullptr;
+ PopupMenu *menu_ot = nullptr;
+ PopupMenu *menu_ot_ss = nullptr;
+ PopupMenu *menu_ot_cv = nullptr;
+ PopupMenu *menu_ot_cu = nullptr;
Tree *lang_list = nullptr;
TreeItem *lang_list_root = nullptr;
+ Label *label_langs = nullptr;
Tree *script_list = nullptr;
TreeItem *script_list_root = nullptr;
- Label *label_langs = nullptr;
Label *label_script = nullptr;
+ Tree *ot_list = nullptr;
+ TreeItem *ot_list_root = nullptr;
+ Label *label_ot = nullptr;
+
void _lang_add();
void _lang_add_item(int p_option);
void _lang_remove(Object *p_item, int p_column, int p_id);
@@ -140,6 +149,10 @@ class DynamicFontImportSettings : public ConfirmationDialog {
void _script_add_item(int p_option);
void _script_remove(Object *p_item, int p_column, int p_id);
+ void _ot_add();
+ void _ot_add_item(int p_option);
+ void _ot_remove(Object *p_item, int p_column, int p_id);
+
// Common
void _add_glyph_range_item(int32_t p_start, int32_t p_end, const String &p_name);
diff --git a/editor/import/resource_importer_dynamicfont.cpp b/editor/import/resource_importer_dynamicfont.cpp
index 54e95f905e..11f563a982 100644
--- a/editor/import/resource_importer_dynamicfont.cpp
+++ b/editor/import/resource_importer_dynamicfont.cpp
@@ -107,6 +107,7 @@ void ResourceImporterDynamicFont::get_import_options(const String &p_path, List<
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_RANGE, "0,10,0.1"), 0.0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides"), Dictionary()));
r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/char_ranges"), Vector<String>()));
r_options->push_back(ImportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "preload/glyph_ranges"), Vector<String>()));
@@ -174,6 +175,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
bool msdf = p_options["multichannel_signed_distance_field"];
int px_range = p_options["msdf_pixel_range"];
int px_size = p_options["msdf_size"];
+ Dictionary ot_ov = p_options["opentype_feature_overrides"];
bool autohinter = p_options["force_autohinter"];
int hinting = p_options["hinting"];
@@ -190,6 +192,7 @@ Error ResourceImporterDynamicFont::import(const String &p_source_file, const Str
font->set_multichannel_signed_distance_field(msdf);
font->set_msdf_pixel_range(px_range);
font->set_msdf_size(px_size);
+ font->set_opentype_feature_overrides(ot_ov);
font->set_fixed_size(0);
font->set_force_autohinter(autohinter);
font->set_hinting((TextServer::Hinting)hinting);
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 459de5d35b..c0029312a7 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -488,10 +488,11 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
color.a *= 0.2;
}
- Vector<Color> colors;
- colors.push_back(color);
- colors.push_back(color);
- colors.push_back(color);
+ Vector<Color> colors = {
+ color,
+ color,
+ color
+ };
blend_space_draw->draw_primitive(points, colors, Vector<Vector2>());
}
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 4b7ad7e325..49bef4acd5 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -288,7 +288,7 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
preview = memnew(TextureRect);
previews_vbox->add_child(preview);
- preview->set_expand(true);
+ preview->set_ignore_texture_size(true);
preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 089c37d7a6..cb84e7ea65 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -3381,10 +3381,11 @@ void CanvasItemEditor::_draw_selection() {
Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE);
viewport->draw_set_transform_matrix(simple_xform);
- Vector<Point2> points;
- points.push_back(Vector2(move_factor.x * EDSCALE, 5 * EDSCALE));
- points.push_back(Vector2(move_factor.x * EDSCALE, -5 * EDSCALE));
- points.push_back(Vector2((move_factor.x + 10) * EDSCALE, 0));
+ Vector<Point2> points = {
+ Vector2(move_factor.x * EDSCALE, 5 * EDSCALE),
+ Vector2(move_factor.x * EDSCALE, -5 * EDSCALE),
+ Vector2((move_factor.x + 10) * EDSCALE, 0)
+ };
viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), SNAME("Editor")));
viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), SNAME("Editor")), Math::round(EDSCALE));
@@ -5823,11 +5824,12 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &
editor_data->get_undo_redo().add_do_property(child, "rect_size", texture_size);
} else if (node_class == "Polygon2D") {
Size2 texture_size = texture->get_size();
- Vector<Vector2> list;
- list.push_back(Vector2(0, 0));
- list.push_back(Vector2(texture_size.width, 0));
- list.push_back(Vector2(texture_size.width, texture_size.height));
- list.push_back(Vector2(0, texture_size.height));
+ Vector<Vector2> list = {
+ Vector2(0, 0),
+ Vector2(texture_size.width, 0),
+ Vector2(texture_size.width, texture_size.height),
+ Vector2(0, texture_size.height)
+ };
editor_data->get_undo_redo().add_do_property(child, "polygon", list);
}
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
index bf6485f9ec..52651ae380 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
@@ -358,6 +358,7 @@ void CollisionPolygon3DEditor::_polygon_draw() {
float depth = _get_depth() * 0.5;
+ m->clear_surfaces();
imesh->clear_surfaces();
imgeom->set_material_override(line_material);
imesh->surface_begin(Mesh::PRIMITIVE_LINES);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 474e84cae8..59ba49232e 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -117,52 +117,52 @@ void EditorNode3DGizmo::redraw() {
}
}
-String EditorNode3DGizmo::get_handle_name(int p_id) const {
+String EditorNode3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
String ret;
- if (GDVIRTUAL_CALL(_get_handle_name, p_id, ret)) {
+ if (GDVIRTUAL_CALL(_get_handle_name, p_id, p_secondary, ret)) {
return ret;
}
ERR_FAIL_COND_V(!gizmo_plugin, "");
- return gizmo_plugin->get_handle_name(this, p_id);
+ return gizmo_plugin->get_handle_name(this, p_id, p_secondary);
}
-bool EditorNode3DGizmo::is_handle_highlighted(int p_id) const {
+bool EditorNode3DGizmo::is_handle_highlighted(int p_id, bool p_secondary) const {
bool success;
- if (GDVIRTUAL_CALL(_is_handle_highlighted, p_id, success)) {
+ if (GDVIRTUAL_CALL(_is_handle_highlighted, p_id, p_secondary, success)) {
return success;
}
ERR_FAIL_COND_V(!gizmo_plugin, false);
- return gizmo_plugin->is_handle_highlighted(this, p_id);
+ return gizmo_plugin->is_handle_highlighted(this, p_id, p_secondary);
}
-Variant EditorNode3DGizmo::get_handle_value(int p_id) const {
+Variant EditorNode3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
Variant value;
- if (GDVIRTUAL_CALL(_get_handle_value, p_id, value)) {
+ if (GDVIRTUAL_CALL(_get_handle_value, p_id, p_secondary, value)) {
return value;
}
ERR_FAIL_COND_V(!gizmo_plugin, Variant());
- return gizmo_plugin->get_handle_value(this, p_id);
+ return gizmo_plugin->get_handle_value(this, p_id, p_secondary);
}
-void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) {
- if (GDVIRTUAL_CALL(_set_handle, p_id, p_camera, p_point)) {
+void EditorNode3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
+ if (GDVIRTUAL_CALL(_set_handle, p_id, p_secondary, p_camera, p_point)) {
return;
}
ERR_FAIL_COND(!gizmo_plugin);
- gizmo_plugin->set_handle(this, p_id, p_camera, p_point);
+ gizmo_plugin->set_handle(this, p_id, p_secondary, p_camera, p_point);
}
-void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) {
- if (GDVIRTUAL_CALL(_commit_handle, p_id, p_restore, p_cancel)) {
+void EditorNode3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
+ if (GDVIRTUAL_CALL(_commit_handle, p_id, p_secondary, p_restore, p_cancel)) {
return;
}
ERR_FAIL_COND(!gizmo_plugin);
- gizmo_plugin->commit_handle(this, p_id, p_restore, p_cancel);
+ gizmo_plugin->commit_handle(this, p_id, p_secondary, p_restore, p_cancel);
}
int EditorNode3DGizmo::subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const {
@@ -324,37 +324,34 @@ void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
ERR_FAIL_COND(!spatial_node);
Instance ins;
- Vector<Vector3> vs;
- Vector<Vector2> uv;
- Vector<Color> colors;
-
- vs.push_back(Vector3(-p_scale, p_scale, 0));
- vs.push_back(Vector3(p_scale, p_scale, 0));
- vs.push_back(Vector3(p_scale, -p_scale, 0));
- vs.push_back(Vector3(-p_scale, -p_scale, 0));
-
- uv.push_back(Vector2(0, 0));
- uv.push_back(Vector2(1, 0));
- uv.push_back(Vector2(1, 1));
- uv.push_back(Vector2(0, 1));
-
- colors.push_back(p_modulate);
- colors.push_back(p_modulate);
- colors.push_back(p_modulate);
- colors.push_back(p_modulate);
+ Vector<Vector3> vs = {
+ Vector3(-p_scale, p_scale, 0),
+ Vector3(p_scale, p_scale, 0),
+ Vector3(p_scale, -p_scale, 0),
+ Vector3(-p_scale, -p_scale, 0)
+ };
+
+ Vector<Vector2> uv = {
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ Vector2(0, 1)
+ };
+
+ Vector<Color> colors = {
+ p_modulate,
+ p_modulate,
+ p_modulate,
+ p_modulate
+ };
+
+ Vector<int> indices = { 0, 1, 2, 0, 2, 3 };
Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[Mesh::ARRAY_VERTEX] = vs;
a[Mesh::ARRAY_TEX_UV] = uv;
- Vector<int> indices;
- indices.push_back(0);
- indices.push_back(1);
- indices.push_back(2);
- indices.push_back(0);
- indices.push_back(2);
- indices.push_back(3);
a[Mesh::ARRAY_INDEX] = indices;
a[Mesh::ARRAY_COLOR] = colors;
mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a);
@@ -410,7 +407,8 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
}
bool is_current_hover_gizmo = Node3DEditor::get_singleton()->get_current_hover_gizmo() == this;
- int current_hover_handle = Node3DEditor::get_singleton()->get_current_hover_gizmo_handle();
+ bool current_hover_handle_secondary;
+ int current_hover_handle = Node3DEditor::get_singleton()->get_current_hover_gizmo_handle(current_hover_handle_secondary);
Instance ins;
Ref<ArrayMesh> mesh = memnew(ArrayMesh);
@@ -424,12 +422,12 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
Color *w = colors.ptrw();
for (int i = 0; i < p_handles.size(); i++) {
Color col(1, 1, 1, 1);
- if (is_handle_highlighted(i)) {
+ if (is_handle_highlighted(i, p_secondary)) {
col = Color(0, 0, 1, 0.9);
}
int id = p_ids.is_empty() ? i : p_ids[i];
- if (!is_current_hover_gizmo || current_hover_handle != id) {
+ if (!is_current_hover_gizmo || current_hover_handle != id || p_secondary != current_hover_handle_secondary) {
col.a = 0.8;
}
@@ -574,8 +572,9 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
return false;
}
-void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id) {
+void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary) {
r_id = -1;
+ r_secondary = false;
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@@ -605,6 +604,7 @@ void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2
} else {
r_id = secondary_handle_ids[i];
}
+ r_secondary = true;
}
}
}
@@ -628,6 +628,7 @@ void EditorNode3DGizmo::handles_intersect_ray(Camera3D *p_camera, const Vector2
} else {
r_id = handle_ids[i];
}
+ r_secondary = false;
}
}
}
@@ -839,12 +840,12 @@ void EditorNode3DGizmo::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_subgizmo_selection"), &EditorNode3DGizmo::get_subgizmo_selection);
GDVIRTUAL_BIND(_redraw);
- GDVIRTUAL_BIND(_get_handle_name, "id");
- GDVIRTUAL_BIND(_is_handle_highlighted, "id");
+ GDVIRTUAL_BIND(_get_handle_name, "id", "secondary");
+ GDVIRTUAL_BIND(_is_handle_highlighted, "id", "secondary");
- GDVIRTUAL_BIND(_get_handle_value, "id");
- GDVIRTUAL_BIND(_set_handle, "id", "camera", "point");
- GDVIRTUAL_BIND(_commit_handle, "id", "restore", "cancel");
+ GDVIRTUAL_BIND(_get_handle_value, "id", "secondary");
+ GDVIRTUAL_BIND(_set_handle, "id", "secondary", "camera", "point");
+ GDVIRTUAL_BIND(_commit_handle, "id", "secondary", "restore", "cancel");
GDVIRTUAL_BIND(_subgizmos_intersect_ray, "camera", "point");
GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "camera", "frustum");
@@ -1054,12 +1055,12 @@ void EditorNode3DGizmoPlugin::_bind_methods() {
GDVIRTUAL_BIND(_is_selectable_when_hidden);
GDVIRTUAL_BIND(_redraw, "gizmo");
- GDVIRTUAL_BIND(_get_handle_name, "gizmo", "handle_id");
- GDVIRTUAL_BIND(_is_handle_highlighted, "gizmo", "handle_id");
- GDVIRTUAL_BIND(_get_handle_value, "gizmo", "handle_id");
+ GDVIRTUAL_BIND(_get_handle_name, "gizmo", "handle_id", "secondary");
+ GDVIRTUAL_BIND(_is_handle_highlighted, "gizmo", "handle_id", "secondary");
+ GDVIRTUAL_BIND(_get_handle_value, "gizmo", "handle_id", "secondary");
- GDVIRTUAL_BIND(_set_handle, "gizmo", "handle_id", "camera", "screen_pos");
- GDVIRTUAL_BIND(_commit_handle, "gizmo", "handle_id", "restore", "cancel");
+ GDVIRTUAL_BIND(_set_handle, "gizmo", "handle_id", "secondary", "camera", "screen_pos");
+ GDVIRTUAL_BIND(_commit_handle, "gizmo", "handle_id", "secondary", "restore", "cancel");
GDVIRTUAL_BIND(_subgizmos_intersect_ray, "gizmo", "camera", "screen_pos");
GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "gizmo", "camera", "frustum_planes");
@@ -1110,36 +1111,36 @@ void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
GDVIRTUAL_CALL(_redraw, p_gizmo);
}
-bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
bool ret;
- if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) {
return ret;
}
return false;
}
-String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
String ret;
- if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) {
return ret;
}
return "";
}
-Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
Variant ret;
- if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, ret)) {
return ret;
}
return Variant();
}
-void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
- GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_camera, p_point);
+void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
+ GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, p_camera, p_point);
}
-void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
- GDVIRTUAL_CALL(_commit_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_restore, p_cancel);
+void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
+ GDVIRTUAL_CALL(_commit_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, p_restore, p_cancel);
}
int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const {
@@ -1244,7 +1245,7 @@ int Light3DGizmoPlugin::get_priority() const {
return -1;
}
-String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
if (p_id == 0) {
return "Radius";
} else {
@@ -1252,7 +1253,7 @@ String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int
}
}
-Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant Light3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
if (p_id == 0) {
return light->get_param(Light3D::PARAM_RANGE);
@@ -1291,7 +1292,7 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec
return Math::rad2deg(a);
}
-void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
Transform3D gt = light->get_global_transform();
Transform3D gi = gt.affine_inverse();
@@ -1335,7 +1336,7 @@ void Light3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
}
}
-void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void Light3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
light->set_param(p_id == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore);
@@ -1477,9 +1478,10 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(points_primary, material_primary, false, color);
p_gizmo->add_lines(points_secondary, material_secondary, false, color);
- Vector<Vector3> handles;
- handles.push_back(Vector3(0, 0, -r));
- handles.push_back(Vector3(w, 0, -d));
+ Vector<Vector3> handles = {
+ Vector3(0, 0, -r),
+ Vector3(w, 0, -d)
+ };
p_gizmo->add_handles(handles, get_material("handles"));
p_gizmo->add_unscaled_billboard(icon, 0.05, color);
@@ -1508,16 +1510,16 @@ int AudioStreamPlayer3DGizmoPlugin::get_priority() const {
return -1;
}
-String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
return "Emission Radius";
}
-Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
return player->get_emission_angle();
}
-void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
Transform3D gt = player->get_global_transform();
@@ -1554,7 +1556,7 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo
}
}
-void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void AudioStreamPlayer3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -1666,7 +1668,7 @@ int Camera3DGizmoPlugin::get_priority() const {
return -1;
}
-String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
@@ -1676,7 +1678,7 @@ String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, in
}
}
-Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
@@ -1686,7 +1688,7 @@ Variant Camera3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo,
}
}
-void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
Transform3D gt = camera->get_global_transform();
@@ -1715,7 +1717,7 @@ void Camera3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
}
}
-void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void Camera3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
@@ -2210,10 +2212,10 @@ void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->clear();
- Vector<Vector3> lines;
-
- lines.push_back(Vector3());
- lines.push_back(Vector3(0, 0, 1.0) * spring_arm->get_length());
+ Vector<Vector3> lines = {
+ Vector3(),
+ Vector3(0, 0, 1.0) * spring_arm->get_length()
+ };
Ref<StandardMaterial3D> material = get_material("shape_material", p_gizmo);
@@ -2370,21 +2372,21 @@ void SoftDynamicBody3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_collision_triangles(tm);
}
-String SoftDynamicBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String SoftDynamicBody3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
return "SoftDynamicBody3D pin point";
}
-Variant SoftDynamicBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant SoftDynamicBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node());
return Variant(soft_body->is_point_pinned(p_id));
}
-void SoftDynamicBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void SoftDynamicBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node());
soft_body->pin_point_toggle(p_id);
}
-bool SoftDynamicBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+bool SoftDynamicBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
SoftDynamicBody3D *soft_body = Object::cast_to<SoftDynamicBody3D>(p_gizmo->get_spatial_node());
return soft_body->is_point_pinned(p_id);
}
@@ -2411,7 +2413,7 @@ int VisibleOnScreenNotifier3DGizmoPlugin::get_priority() const {
return -1;
}
-String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
switch (p_id) {
case 0:
return "Size X";
@@ -2430,12 +2432,12 @@ String VisibleOnScreenNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DG
return "";
}
-Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant VisibleOnScreenNotifier3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node());
return notifier->get_aabb();
}
-void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node());
Transform3D gt = notifier->get_global_transform();
@@ -2487,7 +2489,7 @@ void VisibleOnScreenNotifier3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p
}
}
-void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void VisibleOnScreenNotifier3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
VisibleOnScreenNotifier3D *notifier = Object::cast_to<VisibleOnScreenNotifier3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2603,7 +2605,7 @@ bool GPUParticles3DGizmoPlugin::is_selectable_when_hidden() const {
return true;
}
-String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
switch (p_id) {
case 0:
return "Size X";
@@ -2622,12 +2624,12 @@ String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_giz
return "";
}
-Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant GPUParticles3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
return particles->get_visibility_aabb();
}
-void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
Transform3D gt = particles->get_global_transform();
@@ -2678,7 +2680,7 @@ void GPUParticles3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int
}
}
-void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void GPUParticles3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2764,7 +2766,7 @@ int GPUParticlesCollision3DGizmoPlugin::get_priority() const {
return -1;
}
-String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
const Node3D *cs = p_gizmo->get_spatial_node();
if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) {
@@ -2778,7 +2780,7 @@ String GPUParticlesCollision3DGizmoPlugin::get_handle_name(const EditorNode3DGiz
return "";
}
-Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
const Node3D *cs = p_gizmo->get_spatial_node();
if (Object::cast_to<GPUParticlesCollisionSphere3D>(cs) || Object::cast_to<GPUParticlesAttractorSphere3D>(cs)) {
@@ -2792,7 +2794,7 @@ Variant GPUParticlesCollision3DGizmoPlugin::get_handle_value(const EditorNode3DG
return Variant();
}
-void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Node3D *sn = p_gizmo->get_spatial_node();
Transform3D gt = sn->get_global_transform();
@@ -2838,7 +2840,7 @@ void GPUParticlesCollision3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_g
}
}
-void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Node3D *sn = p_gizmo->get_spatial_node();
if (Object::cast_to<GPUParticlesCollisionSphere3D>(sn) || Object::cast_to<GPUParticlesAttractorSphere3D>(sn)) {
@@ -3027,7 +3029,7 @@ int ReflectionProbeGizmoPlugin::get_priority() const {
return -1;
}
-String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
switch (p_id) {
case 0:
return "Extents X";
@@ -3046,12 +3048,12 @@ String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gi
return "";
}
-Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant ReflectionProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
return AABB(probe->get_extents(), probe->get_origin_offset());
}
-void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
Transform3D gt = probe->get_global_transform();
@@ -3108,7 +3110,7 @@ void ReflectionProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, in
}
}
-void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void ReflectionProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
AABB restore = p_restore;
@@ -3212,7 +3214,7 @@ int DecalGizmoPlugin::get_priority() const {
return -1;
}
-String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
switch (p_id) {
case 0:
return "Extents X";
@@ -3225,12 +3227,12 @@ String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p
return "";
}
-Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant DecalGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
return decal->get_extents();
}
-void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Transform3D gt = decal->get_global_transform();
@@ -3261,7 +3263,7 @@ void DecalGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Ca
decal->set_extents(extents);
}
-void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void DecalGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -3352,7 +3354,7 @@ int VoxelGIGizmoPlugin::get_priority() const {
return -1;
}
-String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
switch (p_id) {
case 0:
return "Extents X";
@@ -3365,12 +3367,12 @@ String VoxelGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int
return "";
}
-Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant VoxelGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node());
return probe->get_extents();
}
-void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node());
Transform3D gt = probe->get_global_transform();
@@ -3401,7 +3403,7 @@ void VoxelGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id,
probe->set_extents(extents);
}
-void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void VoxelGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
VoxelGI *probe = Object::cast_to<VoxelGI>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -3521,20 +3523,6 @@ LightmapGIGizmoPlugin::LightmapGIGizmoPlugin() {
create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon(SNAME("GizmoLightmapGI"), SNAME("EditorIcons")));
}
-String LightmapGIGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- return "";
-}
-
-Variant LightmapGIGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- return Variant();
-}
-
-void LightmapGIGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
-}
-
-void LightmapGIGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
-}
-
bool LightmapGIGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<LightmapGI>(p_spatial) != nullptr;
}
@@ -3703,20 +3691,6 @@ LightmapProbeGizmoPlugin::LightmapProbeGizmoPlugin() {
create_material("lightprobe_lines", gizmo_color);
}
-String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- return "";
-}
-
-Variant LightmapProbeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- return Variant();
-}
-
-void LightmapProbeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
-}
-
-void LightmapProbeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
-}
-
bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<LightmapProbe>(p_spatial) != nullptr;
}
@@ -3863,7 +3837,7 @@ int CollisionShape3DGizmoPlugin::get_priority() const {
return -1;
}
-String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
@@ -3894,7 +3868,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
return "";
}
-Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
@@ -3930,7 +3904,7 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
return Variant();
}
-void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
@@ -4044,7 +4018,7 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
}
}
-void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
@@ -4296,9 +4270,10 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_collision_segments(collision_segments);
- Vector<Vector3> handles;
- handles.push_back(Vector3(cs2->get_radius(), 0, 0));
- handles.push_back(Vector3(0, cs2->get_height() * 0.5, 0));
+ Vector<Vector3> handles = {
+ Vector3(cs2->get_radius(), 0, 0),
+ Vector3(0, cs2->get_height() * 0.5, 0)
+ };
p_gizmo->add_handles(handles, handles_material);
}
@@ -4352,16 +4327,16 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_collision_segments(collision_segments);
- Vector<Vector3> handles;
- handles.push_back(Vector3(cs2->get_radius(), 0, 0));
- handles.push_back(Vector3(0, cs2->get_height() * 0.5, 0));
+ Vector<Vector3> handles = {
+ Vector3(cs2->get_radius(), 0, 0),
+ Vector3(0, cs2->get_height() * 0.5, 0)
+ };
p_gizmo->add_handles(handles, handles_material);
}
if (Object::cast_to<WorldBoundaryShape3D>(*s)) {
Ref<WorldBoundaryShape3D> wbs = s;
const Plane &p = wbs->get_plane();
- Vector<Vector3> points;
Vector3 n1 = p.get_any_perpendicular_normal();
Vector3 n2 = p.normal.cross(n1).normalized();
@@ -4373,16 +4348,18 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p.normal * p.d + n1 * -10.0 + n2 * 10.0,
};
- points.push_back(pface[0]);
- points.push_back(pface[1]);
- points.push_back(pface[1]);
- points.push_back(pface[2]);
- points.push_back(pface[2]);
- points.push_back(pface[3]);
- points.push_back(pface[3]);
- points.push_back(pface[0]);
- points.push_back(p.normal * p.d);
- points.push_back(p.normal * p.d + p.normal * 3);
+ Vector<Vector3> points = {
+ pface[0],
+ pface[1],
+ pface[1],
+ pface[2],
+ pface[2],
+ pface[3],
+ pface[3],
+ pface[0],
+ p.normal * p.d,
+ p.normal * p.d + p.normal * 3
+ };
p_gizmo->add_lines(points, material);
p_gizmo->add_collision_segments(points);
@@ -4419,9 +4396,10 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (Object::cast_to<SeparationRayShape3D>(*s)) {
Ref<SeparationRayShape3D> rs = s;
- Vector<Vector3> points;
- points.push_back(Vector3());
- points.push_back(Vector3(0, 0, rs->get_length()));
+ Vector<Vector3> points = {
+ Vector3(),
+ Vector3(0, 0, rs->get_length())
+ };
p_gizmo->add_lines(points, material);
p_gizmo->add_collision_segments(points);
Vector<Vector3> handles;
@@ -5298,15 +5276,15 @@ int FogVolumeGizmoPlugin::get_priority() const {
return -1;
}
-String FogVolumeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String FogVolumeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
return "Extents";
}
-Variant FogVolumeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant FogVolumeGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
return Vector3(p_gizmo->get_spatial_node()->call("get_extents"));
}
-void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Node3D *sn = p_gizmo->get_spatial_node();
Transform3D gt = sn->get_global_transform();
@@ -5335,7 +5313,7 @@ void FogVolumeGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id
sn->call("set_extents", he);
}
-void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void FogVolumeGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Node3D *sn = p_gizmo->get_spatial_node();
if (p_cancel) {
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index a8383aefed..66b3f02fcf 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -80,12 +80,11 @@ protected:
EditorNode3DGizmoPlugin *gizmo_plugin;
GDVIRTUAL0(_redraw)
- GDVIRTUAL1RC(String, _get_handle_name, int)
- GDVIRTUAL1RC(bool, _is_handle_highlighted, int)
-
- GDVIRTUAL1RC(Variant, _get_handle_value, int)
- GDVIRTUAL3(_set_handle, int, const Camera3D *, Vector2)
- GDVIRTUAL3(_commit_handle, int, Variant, bool)
+ GDVIRTUAL2RC(String, _get_handle_name, int, bool)
+ GDVIRTUAL2RC(bool, _is_handle_highlighted, int, bool)
+ GDVIRTUAL2RC(Variant, _get_handle_value, int, bool)
+ GDVIRTUAL4(_set_handle, int, bool, const Camera3D *, Vector2)
+ GDVIRTUAL4(_commit_handle, int, bool, Variant, bool)
GDVIRTUAL2RC(int, _subgizmos_intersect_ray, const Camera3D *, Vector2)
GDVIRTUAL2RC(Vector<int>, _subgizmos_intersect_frustum, const Camera3D *, TypedArray<Plane>)
@@ -102,11 +101,11 @@ public:
void add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, const Vector<int> &p_ids = Vector<int>(), bool p_billboard = false, bool p_secondary = false);
void add_solid_box(Ref<Material> &p_material, Vector3 p_size, Vector3 p_position = Vector3(), const Transform3D &p_xform = Transform3D());
- virtual bool is_handle_highlighted(int p_id) const;
- virtual String get_handle_name(int p_id) const;
- virtual Variant get_handle_value(int p_id) const;
- virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point);
- virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false);
+ virtual bool is_handle_highlighted(int p_id, bool p_secondary) const;
+ virtual String get_handle_name(int p_id, bool p_secondary) const;
+ virtual Variant get_handle_value(int p_id, bool p_secondary) const;
+ virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point);
+ virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);
virtual int subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
@@ -121,7 +120,7 @@ public:
Node3D *get_spatial_node() const { return spatial_node; }
Ref<EditorNode3DGizmoPlugin> get_plugin() const { return gizmo_plugin; }
bool intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum);
- void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id);
+ void handles_intersect_ray(Camera3D *p_camera, const Vector2 &p_point, bool p_shift_pressed, int &r_id, bool &r_secondary);
bool intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal);
bool is_subgizmo_selected(int p_id) const;
Vector<int> get_subgizmo_selection() const;
@@ -167,12 +166,12 @@ protected:
GDVIRTUAL0RC(bool, _is_selectable_when_hidden)
GDVIRTUAL1(_redraw, Ref<EditorNode3DGizmo>)
- GDVIRTUAL2RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int)
- GDVIRTUAL2RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int)
- GDVIRTUAL2RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int)
+ GDVIRTUAL3RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int, bool)
+ GDVIRTUAL3RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int, bool)
+ GDVIRTUAL3RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int, bool)
- GDVIRTUAL4(_set_handle, Ref<EditorNode3DGizmo>, int, const Camera3D *, Vector2)
- GDVIRTUAL4(_commit_handle, Ref<EditorNode3DGizmo>, int, Variant, bool)
+ GDVIRTUAL5(_set_handle, Ref<EditorNode3DGizmo>, int, bool, const Camera3D *, Vector2)
+ GDVIRTUAL5(_commit_handle, Ref<EditorNode3DGizmo>, int, bool, Variant, bool)
GDVIRTUAL3RC(int, _subgizmos_intersect_ray, Ref<EditorNode3DGizmo>, const Camera3D *, Vector2)
GDVIRTUAL3RC(Vector<int>, _subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>, const Camera3D *, TypedArray<Plane>)
@@ -194,11 +193,11 @@ public:
virtual bool is_selectable_when_hidden() const;
virtual void redraw(EditorNode3DGizmo *p_gizmo);
- virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const;
- virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const;
- virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const;
- virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point);
- virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false);
+ virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
+ virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
+ virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
+ virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point);
+ virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);
virtual int subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const;
virtual Vector<int> subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const;
@@ -223,10 +222,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Light3DGizmoPlugin();
@@ -240,10 +239,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
AudioStreamPlayer3DGizmoPlugin();
@@ -270,10 +269,10 @@ public:
String get_gizmo_name() const override;
int get_priority() const override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
Camera3DGizmoPlugin();
@@ -390,10 +389,10 @@ public:
bool is_selectable_when_hidden() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
- bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
+ bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
SoftDynamicBody3DGizmoPlugin();
};
@@ -407,10 +406,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
VisibleOnScreenNotifier3DGizmoPlugin();
};
@@ -437,10 +436,10 @@ public:
bool is_selectable_when_hidden() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
GPUParticles3DGizmoPlugin();
};
@@ -454,10 +453,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
GPUParticlesCollision3DGizmoPlugin();
};
@@ -471,10 +470,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
ReflectionProbeGizmoPlugin();
};
@@ -488,10 +487,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
DecalGizmoPlugin();
};
@@ -505,10 +504,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
VoxelGIGizmoPlugin();
};
@@ -522,11 +521,6 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
-
LightmapGIGizmoPlugin();
};
@@ -539,11 +533,6 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
-
LightmapProbeGizmoPlugin();
};
@@ -568,10 +557,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
CollisionShape3DGizmoPlugin();
};
@@ -678,10 +667,10 @@ public:
int get_priority() const override;
void redraw(EditorNode3DGizmo *p_gizmo) override;
- String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
FogVolumeGizmoPlugin();
};
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 957d1483bc..6ea8fba9b5 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -423,6 +423,7 @@ Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const {
void Node3DEditorViewport::_clear_selected() {
_edit.gizmo = Ref<EditorNode3DGizmo>();
_edit.gizmo_handle = -1;
+ _edit.gizmo_handle_secondary = false;
_edit.gizmo_initial_value = Variant();
Node3D *selected = spatial_editor->get_single_selected_node();
@@ -1358,7 +1359,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed() && _edit.gizmo.is_valid()) {
//restore
- _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true);
+ _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, true);
_edit.gizmo = Ref<EditorNode3DGizmo>();
}
@@ -1496,11 +1497,13 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
int gizmo_handle = -1;
- seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle);
+ bool gizmo_secondary = false;
+ seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle, gizmo_secondary);
if (gizmo_handle != -1) {
_edit.gizmo = seg;
_edit.gizmo_handle = gizmo_handle;
- _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle);
+ _edit.gizmo_handle_secondary = gizmo_secondary;
+ _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle, gizmo_secondary);
intersected_handle = true;
break;
}
@@ -1612,7 +1615,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
surface->update();
} else {
if (_edit.gizmo.is_valid()) {
- _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false);
+ _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, false);
_edit.gizmo = Ref<EditorNode3DGizmo>();
break;
}
@@ -1694,6 +1697,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<EditorNode3DGizmo> found_gizmo;
int found_handle = -1;
+ bool found_handle_secondary = false;
for (int i = 0; i < gizmos.size(); i++) {
Ref<EditorNode3DGizmo> seg = gizmos[i];
@@ -1701,7 +1705,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
continue;
}
- seg->handles_intersect_ray(camera, _edit.mouse_pos, false, found_handle);
+ seg->handles_intersect_ray(camera, _edit.mouse_pos, false, found_handle, found_handle_secondary);
if (found_handle != -1) {
found_gizmo = seg;
@@ -1713,9 +1717,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
spatial_editor->select_gizmo_highlight_axis(-1);
}
- if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != spatial_editor->get_current_hover_gizmo_handle()) {
+ bool current_hover_handle_secondary = false;
+ int curreny_hover_handle = spatial_editor->get_current_hover_gizmo_handle(current_hover_handle_secondary);
+ if (found_gizmo != spatial_editor->get_current_hover_gizmo() || found_handle != curreny_hover_handle || found_handle_secondary != current_hover_handle_secondary) {
spatial_editor->set_current_hover_gizmo(found_gizmo);
- spatial_editor->set_current_hover_gizmo_handle(found_handle);
+ spatial_editor->set_current_hover_gizmo_handle(found_handle, found_handle_secondary);
spatial_editor->get_single_selected_node()->update_gizmos();
}
}
@@ -1728,9 +1734,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
NavigationMode nav_mode = NAVIGATION_NONE;
if (_edit.gizmo.is_valid()) {
- _edit.gizmo->set_handle(_edit.gizmo_handle, camera, m->get_position());
- Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle);
- String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
+ _edit.gizmo->set_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, camera, m->get_position());
+ Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle, _edit.gizmo_handle_secondary);
+ String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle, _edit.gizmo_handle_secondary);
set_message(n + ": " + String(v));
} else if ((m->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
@@ -4301,6 +4307,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
_edit.plane = TRANSFORM_VIEW;
_edit.snap = true;
_edit.gizmo_handle = -1;
+ _edit.gizmo_handle_secondary = false;
index = p_index;
editor = p_editor;
@@ -5306,6 +5313,7 @@ void Node3DEditor::edit(Node3D *p_spatial) {
selected = p_spatial;
current_hover_gizmo = Ref<EditorNode3DGizmo>();
current_hover_gizmo_handle = -1;
+ current_hover_gizmo_handle_secondary = false;
if (selected) {
Vector<Ref<Node3DGizmo>> gizmos = selected->get_gizmos();
@@ -7676,6 +7684,7 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
EDITOR_DEF("editors/3d/navigation/show_viewport_rotation_gizmo", true);
current_hover_gizmo_handle = -1;
+ current_hover_gizmo_handle_secondary = false;
{
//sun popup
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 8d42e88b53..da560f4d83 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -312,6 +312,7 @@ private:
bool snap = false;
Ref<EditorNode3DGizmo> gizmo;
int gizmo_handle = 0;
+ bool gizmo_handle_secondary = false;
Variant gizmo_initial_value;
} _edit;
@@ -554,6 +555,7 @@ private:
Ref<Node3DGizmo> current_hover_gizmo;
int current_hover_gizmo_handle;
+ bool current_hover_gizmo_handle_secondary;
real_t snap_translate_value;
real_t snap_rotate_value;
@@ -810,8 +812,15 @@ public:
Ref<EditorNode3DGizmo> get_current_hover_gizmo() const { return current_hover_gizmo; }
void set_current_hover_gizmo(Ref<EditorNode3DGizmo> p_gizmo) { current_hover_gizmo = p_gizmo; }
- void set_current_hover_gizmo_handle(int p_id) { current_hover_gizmo_handle = p_id; }
- int get_current_hover_gizmo_handle() const { return current_hover_gizmo_handle; }
+ void set_current_hover_gizmo_handle(int p_id, bool p_secondary) {
+ current_hover_gizmo_handle = p_id;
+ current_hover_gizmo_handle_secondary = p_secondary;
+ }
+
+ int get_current_hover_gizmo_handle(bool &r_secondary) const {
+ r_secondary = current_hover_gizmo_handle_secondary;
+ return current_hover_gizmo_handle;
+ }
void set_can_preview(Camera3D *p_preview);
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index c31b893498..cb62dcdccc 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -36,17 +36,17 @@
#include "node_3d_editor_plugin.h"
#include "scene/resources/curve.h"
-String Path3DGizmo::get_handle_name(int p_id) const {
+String Path3DGizmo::get_handle_name(int p_id, bool p_secondary) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return "";
}
- if (p_id < c->get_point_count()) {
+ if (!p_secondary) {
return TTR("Curve Point #") + itos(p_id);
}
- p_id = p_id - c->get_point_count() + 1;
+ p_id += 1; // Account for the first point only having an "out" handle
int idx = p_id / 2;
int t = p_id % 2;
@@ -60,18 +60,18 @@ String Path3DGizmo::get_handle_name(int p_id) const {
return n;
}
-Variant Path3DGizmo::get_handle_value(int p_id) const {
+Variant Path3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return Variant();
}
- if (p_id < c->get_point_count()) {
+ if (!p_secondary) {
original = c->get_point_position(p_id);
return original;
}
- p_id = p_id - c->get_point_count() + 1;
+ p_id += 1; // Account for the first point only having an "out" handle
int idx = p_id / 2;
int t = p_id % 2;
@@ -88,7 +88,7 @@ Variant Path3DGizmo::get_handle_value(int p_id) const {
return ofs;
}
-void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
@@ -100,7 +100,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
// Setting curve point positions
- if (p_id < c->get_point_count()) {
+ if (!p_secondary) {
const Plane p = Plane(p_camera->get_transform().basis.get_axis(2), gt.xform(original));
Vector3 inters;
@@ -118,7 +118,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point
return;
}
- p_id = p_id - c->get_point_count() + 1;
+ p_id += 1; // Account for the first point only having an "out" handle
int idx = p_id / 2;
int t = p_id % 2;
@@ -157,7 +157,7 @@ void Path3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point
}
}
-void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) {
+void Path3DGizmo::commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null()) {
return;
@@ -165,7 +165,7 @@ void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cance
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
- if (p_id < c->get_point_count()) {
+ if (!p_secondary) {
if (p_cancel) {
c->set_point_position(p_id, p_restore);
return;
@@ -178,7 +178,7 @@ void Path3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cance
return;
}
- p_id = p_id - c->get_point_count() + 1;
+ p_id += 1; // Account for the first point only having an "out" handle
int idx = p_id / 2;
int t = p_id % 2;
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index a7da2c07e5..adda648868 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -45,10 +45,10 @@ class Path3DGizmo : public EditorNode3DGizmo {
mutable float orig_out_length;
public:
- virtual String get_handle_name(int p_idx) const override;
- virtual Variant get_handle_value(int p_id) const override;
- virtual void set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- virtual void commit_handle(int p_id, const Variant &p_restore, bool p_cancel = false) override;
+ virtual String get_handle_name(int p_id, bool p_secondary) const override;
+ virtual Variant get_handle_value(int p_id, bool p_secondary) const override;
+ virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;
virtual void redraw() override;
Path3DGizmo(Path3D *p_path = nullptr);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index e8bbeb0834..afecada1db 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -205,7 +205,7 @@ void ShaderTextEditor::_check_shader_mode() {
static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
- return RS::global_variable_type_get_shader_datatype(gvt);
+ return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt);
}
void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) {
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index cc90d381a5..db2d1438b3 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -40,7 +40,7 @@
#include "scene/gui/text_edit.h"
#include "scene/main/timer.h"
#include "scene/resources/shader.h"
-#include "servers/rendering/shader_language.h"
+#include "servers/rendering/shader_warnings.h"
class ShaderTextEditor : public CodeTextEditor {
GDCLASS(ShaderTextEditor, CodeTextEditor);
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 460eb994e5..2da4f80751 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -1232,7 +1232,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
split_sheet_vb->add_child(split_sheet_panel);
split_sheet_preview = memnew(TextureRect);
- split_sheet_preview->set_expand(true);
+ split_sheet_preview->set_ignore_texture_size(true);
split_sheet_preview->set_mouse_filter(MOUSE_FILTER_PASS);
split_sheet_preview->connect("draw", callable_mp(this, &SpriteFramesEditor::_sheet_preview_draw));
split_sheet_preview->connect("gui_input", callable_mp(this, &SpriteFramesEditor::_sheet_preview_input));
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index a07cc299f2..84b33f0986 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -84,7 +84,7 @@ TexturePreview::TexturePreview(Ref<Texture2D> p_texture, bool p_show_metadata) {
texture_display->set_texture(p_texture);
texture_display->set_anchors_preset(TextureRect::PRESET_WIDE);
texture_display->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
- texture_display->set_expand(true);
+ texture_display->set_ignore_texture_size(true);
add_child(texture_display);
if (p_show_metadata) {
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index c03e55be69..900bf4ef57 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -36,10 +36,6 @@
#include "editor/editor_scale.h"
#include "scene/gui/check_box.h"
-/**
- @author Mariano Suligoy
-*/
-
void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) {
Vector2 line = (to - from).normalized() * 10;
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index 23981ddb81..bffc6fd9bf 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -40,10 +40,6 @@
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
-/**
- @author Mariano Suligoy
-*/
-
class TextureRegionEditor : public VBoxContainer {
GDCLASS(TextureRegionEditor, VBoxContainer);
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index bf30b595fe..fc4764f61e 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -301,7 +301,7 @@ AtlasMergingDialog::AtlasMergingDialog() {
preview = memnew(TextureRect);
preview->set_h_size_flags(Control::SIZE_EXPAND_FILL);
preview->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- preview->set_expand(true);
+ preview->set_ignore_texture_size(true);
preview->hide();
preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
atlas_merging_right_panel->add_child(preview);
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index c85956991a..24ede3b85e 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -37,57 +37,31 @@
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
#include "scene/gui/texture_rect.h"
+#include "scene/gui/view_panner.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) {
- Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_valid()) {
- drag_type = DRAG_TYPE_NONE;
-
- Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_LEFT) - (mb->get_button_index() == MouseButton::WHEEL_RIGHT), (mb->get_button_index() == MouseButton::WHEEL_UP) - (mb->get_button_index() == MouseButton::WHEEL_DOWN));
- if (scroll_vec != Vector2()) {
- if (mb->is_ctrl_pressed()) {
- if (mb->is_shift_pressed()) {
- panning.x += 32 * mb->get_factor() * scroll_vec.y;
- panning.y += 32 * mb->get_factor() * scroll_vec.x;
- } else {
- panning.y += 32 * mb->get_factor() * scroll_vec.y;
- panning.x += 32 * mb->get_factor() * scroll_vec.x;
- }
-
- emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
- _update_zoom_and_panning(true);
- accept_event();
+ if (panner->gui_input(p_event)) {
+ accept_event();
+ }
+}
- } else if (!mb->is_shift_pressed()) {
- zoom_widget->set_zoom_by_increments(scroll_vec.y * 2);
- emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
- _update_zoom_and_panning(true);
- accept_event();
- }
- }
+void TileAtlasView::_scroll_callback(Vector2 p_scroll_vec) {
+ _pan_callback(-p_scroll_vec * 32);
+}
- if (mb->get_button_index() == MouseButton::MIDDLE || mb->get_button_index() == MouseButton::RIGHT) {
- if (mb->is_pressed()) {
- drag_type = DRAG_TYPE_PAN;
- } else {
- drag_type = DRAG_TYPE_NONE;
- }
- accept_event();
- }
- }
+void TileAtlasView::_pan_callback(Vector2 p_scroll_vec) {
+ panning += p_scroll_vec;
+ emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
+ _update_zoom_and_panning(true);
+}
- Ref<InputEventMouseMotion> mm = p_event;
- if (mm.is_valid()) {
- if (drag_type == DRAG_TYPE_PAN) {
- panning += mm->get_relative();
- _update_zoom_and_panning();
- emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
- accept_event();
- }
- }
+void TileAtlasView::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ zoom_widget->set_zoom_by_increments(-p_scroll_vec.y * 2);
+ emit_signal(SNAME("transform_changed"), zoom_widget->get_zoom(), panning);
+ _update_zoom_and_panning(true);
}
Size2i TileAtlasView::_compute_base_tiles_control_size() {
@@ -548,6 +522,11 @@ void TileAtlasView::update() {
void TileAtlasView::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
+ panner->set_control_scheme((ViewPanner::ControlScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
+ break;
+
case NOTIFICATION_READY:
button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
break;
@@ -561,6 +540,9 @@ void TileAtlasView::_bind_methods() {
TileAtlasView::TileAtlasView() {
set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
+ panner.instantiate();
+ panner->set_callbacks(callable_mp(this, &TileAtlasView::_scroll_callback), callable_mp(this, &TileAtlasView::_pan_callback), callable_mp(this, &TileAtlasView::_zoom_callback));
+
Panel *panel = memnew(Panel);
panel->set_clip_contents(true);
panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h
index ca7f083132..6a0e0ae820 100644
--- a/editor/plugins/tiles/tile_atlas_view.h
+++ b/editor/plugins/tiles/tile_atlas_view.h
@@ -41,6 +41,8 @@
#include "scene/gui/texture_rect.h"
#include "scene/resources/tile_set.h"
+class ViewPanner;
+
class TileAtlasView : public Control {
GDCLASS(TileAtlasView, Control);
@@ -64,6 +66,11 @@ private:
void _center_view();
virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ Ref<ViewPanner> panner;
+ void _scroll_callback(Vector2 p_scroll_vec);
+ void _pan_callback(Vector2 p_scroll_vec);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+
Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache;
void _update_alternative_tiles_rect_cache();
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 03797b1797..f05ff72e5d 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -2445,6 +2445,14 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
vsnode->set_script(add_options[p_idx].script);
}
+ bool is_texture2d = (Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr()) != nullptr);
+ bool is_texture3d = (Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr()) != nullptr);
+ bool is_texture2d_array = (Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr()) != nullptr);
+ bool is_cubemap = (Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr()) != nullptr);
+ bool is_curve = (Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr()) != nullptr);
+ bool is_curve_xyz = (Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr()) != nullptr);
+ bool is_uniform = (Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr()) != nullptr);
+
Point2 position = graph->get_scroll_ofs();
if (saved_node_pos_dirty) {
@@ -2570,23 +2578,32 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
}
}
}
+
+ if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
+ if (is_texture2d) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeTexture::SOURCE_PORT);
+ }
+ if (is_texture3d || is_texture2d_array) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeSample3D::SOURCE_PORT);
+ }
+ if (is_cubemap) {
+ undo_redo->add_do_method(vsnode.ptr(), "set_source", VisualShaderNodeCubemap::SOURCE_PORT);
+ }
+ }
}
}
_member_cancel();
- VisualShaderNodeUniform *uniform = Object::cast_to<VisualShaderNodeUniform>(vsnode.ptr());
- if (uniform) {
+ if (is_uniform) {
undo_redo->add_do_method(this, "_update_uniforms", true);
undo_redo->add_undo_method(this, "_update_uniforms", true);
}
- VisualShaderNodeCurveTexture *curve = Object::cast_to<VisualShaderNodeCurveTexture>(vsnode.ptr());
- if (curve) {
+ if (is_curve) {
graph_plugin->call_deferred(SNAME("update_curve"), id_to_use);
}
- VisualShaderNodeCurveXYZTexture *curve_xyz = Object::cast_to<VisualShaderNodeCurveXYZTexture>(vsnode.ptr());
- if (curve_xyz) {
+ if (is_curve_xyz) {
graph_plugin->call_deferred(SNAME("update_curve_xyz"), id_to_use);
}
@@ -2595,22 +2612,17 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
} else {
//post-initialization
- VisualShaderNodeTexture *texture2d = Object::cast_to<VisualShaderNodeTexture>(vsnode.ptr());
- VisualShaderNodeTexture3D *texture3d = Object::cast_to<VisualShaderNodeTexture3D>(vsnode.ptr());
-
- if (texture2d || texture3d || curve || curve_xyz) {
+ if (is_texture2d || is_texture3d || is_curve || is_curve_xyz) {
undo_redo->add_do_method(vsnode.ptr(), "set_texture", ResourceLoader::load(p_resource_path));
return;
}
- VisualShaderNodeCubemap *cubemap = Object::cast_to<VisualShaderNodeCubemap>(vsnode.ptr());
- if (cubemap) {
+ if (is_cubemap) {
undo_redo->add_do_method(vsnode.ptr(), "set_cube_map", ResourceLoader::load(p_resource_path));
return;
}
- VisualShaderNodeTexture2DArray *texture2d_array = Object::cast_to<VisualShaderNodeTexture2DArray>(vsnode.ptr());
- if (texture2d_array) {
+ if (is_texture2d_array) {
undo_redo->add_do_method(vsnode.ptr(), "set_texture_array", ResourceLoader::load(p_resource_path));
}
}
@@ -3209,6 +3221,10 @@ void VisualShaderEditor::_notification(int p_what) {
}
}
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
+ }
+
if (p_what == NOTIFICATION_DRAG_BEGIN) {
Dictionary dd = get_viewport()->gui_get_drag_data();
if (members->is_visible_in_tree() && dd.has("id")) {
@@ -3910,7 +3926,7 @@ void VisualShaderEditor::_preview_size_changed() {
static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
- return RS::global_variable_type_get_shader_datatype(gvt);
+ return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt);
}
void VisualShaderEditor::_update_preview() {
@@ -5260,21 +5276,26 @@ Size2 VisualShaderNodePortPreview::get_minimum_size() const {
void VisualShaderNodePortPreview::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
- Vector<Vector2> points;
- Vector<Vector2> uvs;
- Vector<Color> colors;
- points.push_back(Vector2());
- uvs.push_back(Vector2(0, 0));
- colors.push_back(Color(1, 1, 1, 1));
- points.push_back(Vector2(get_size().width, 0));
- uvs.push_back(Vector2(1, 0));
- colors.push_back(Color(1, 1, 1, 1));
- points.push_back(get_size());
- uvs.push_back(Vector2(1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- points.push_back(Vector2(0, get_size().height));
- uvs.push_back(Vector2(0, 1));
- colors.push_back(Color(1, 1, 1, 1));
+ Vector<Vector2> points = {
+ Vector2(),
+ Vector2(get_size().width, 0),
+ get_size(),
+ Vector2(0, get_size().height)
+ };
+
+ Vector<Vector2> uvs = {
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ Vector2(0, 1)
+ };
+
+ Vector<Color> colors = {
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1)
+ };
draw_primitive(points, colors, uvs);
}
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 2d6775d02e..9bd8c1e227 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -265,10 +265,25 @@ void ProjectExportDialog::_edit_preset(int p_index) {
export_templates_error->hide();
}
+ export_warning->hide();
export_button->set_disabled(true);
get_ok_button()->set_disabled(true);
-
} else {
+ if (error != String()) {
+ Vector<String> items = error.split("\n", false);
+ error = "";
+ for (int i = 0; i < items.size(); i++) {
+ if (i > 0) {
+ error += "\n";
+ }
+ error += " - " + items[i];
+ }
+ export_warning->set_text(error);
+ export_warning->show();
+ } else {
+ export_warning->hide();
+ }
+
export_error->hide();
export_templates_error->hide();
export_button->set_disabled(false);
@@ -1247,6 +1262,11 @@ ProjectExportDialog::ProjectExportDialog() {
export_error->hide();
export_error->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ export_warning = memnew(Label);
+ main_vb->add_child(export_warning);
+ export_warning->hide();
+ export_warning->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+
export_templates_error = memnew(HBoxContainer);
main_vb->add_child(export_templates_error);
export_templates_error->hide();
diff --git a/editor/project_export.h b/editor/project_export.h
index 5dcda0a9b9..af7ec083c4 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -99,6 +99,7 @@ private:
Label *script_key_error;
Label *export_error;
+ Label *export_warning;
HBoxContainer *export_templates_error;
String default_filename;
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index b710eb2546..1bf6243bcc 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -275,10 +275,8 @@ void ProjectSettingsEditor::_editor_restart_close() {
void ProjectSettingsEditor::_action_added(const String &p_name) {
String name = "input/" + p_name;
- if (ProjectSettings::get_singleton()->has_setting(name)) {
- action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), name));
- return;
- }
+ ERR_FAIL_COND_MSG(ProjectSettings::get_singleton()->has_setting(name),
+ "An action with this name already exists.");
Dictionary action;
action["events"] = Array();
@@ -351,10 +349,8 @@ void ProjectSettingsEditor::_action_renamed(const String &p_old_name, const Stri
const String old_property_name = "input/" + p_old_name;
const String new_property_name = "input/" + p_new_name;
- if (ProjectSettings::get_singleton()->has_setting(new_property_name)) {
- action_map->show_message(vformat(TTR("An action with the name '%s' already exists."), new_property_name));
- return;
- }
+ ERR_FAIL_COND_MSG(ProjectSettings::get_singleton()->has_setting(new_property_name),
+ "An action with this name already exists.");
int order = ProjectSettings::get_singleton()->get_order(old_property_name);
Dictionary action = ProjectSettings::get_singleton()->get(old_property_name);
diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h
index 7a882dc693..9d02fb10bd 100644
--- a/editor/rename_dialog.h
+++ b/editor/rename_dialog.h
@@ -41,10 +41,6 @@
#include "scene/gui/option_button.h"
#include "scene/gui/spin_box.h"
-/**
-@author Blazej Floch
-*/
-
class RenameDialog : public ConfirmationDialog {
GDCLASS(RenameDialog, ConfirmationDialog);
diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h
index 3d76eb3294..981829a871 100644
--- a/editor/reparent_dialog.h
+++ b/editor/reparent_dialog.h
@@ -37,9 +37,7 @@
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
-/**
-@author Juan Linietsky <reduzio@gmail.com>
-*/
+
class ReparentDialog : public ConfirmationDialog {
GDCLASS(ReparentDialog, ConfirmationDialog);
@@ -60,4 +58,4 @@ public:
~ReparentDialog();
};
-#endif
+#endif // REPARENT_DIALOG_H
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
index f97ffcae65..2f3867a58c 100644
--- a/editor/shader_globals_editor.cpp
+++ b/editor/shader_globals_editor.cpp
@@ -30,6 +30,7 @@
#include "shader_globals_editor.h"
#include "editor_node.h"
+#include "servers/rendering/shader_language.h"
static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = {
"bool",
diff --git a/editor/translations/af.po b/editor/translations/af.po
index fb80e360f9..f139124259 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -373,6 +373,7 @@ msgstr "Skep %d NUWE bane en voeg sleutels by?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -853,6 +854,7 @@ msgstr "Voeg By"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -904,8 +906,7 @@ msgstr "Koppel tans Sein:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2005,7 +2006,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Verfris"
@@ -2128,7 +2128,8 @@ msgstr "Gidse & Lêers:"
msgid "Preview:"
msgstr "Voorskou:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Lêer:"
@@ -2316,7 +2317,7 @@ msgstr "Metodes"
msgid "Signal"
msgstr "Seine"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstant"
@@ -2348,6 +2349,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3056,7 +3059,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "Projek Stigters"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3194,11 +3197,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Wissel Modus"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3419,6 +3417,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3500,7 +3499,6 @@ msgid "Author"
msgstr "Outeurs"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3729,6 +3727,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Fout terwyl laai:"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4645,6 +4649,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6375,6 +6380,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9839,7 +9845,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9847,7 +9853,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9855,10 +9866,41 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Verander Skikking Waarde-Soort"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Verander Skikking Waarde-Soort"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Herset Zoem"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9867,7 +9909,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Skuif Gunsteling Op"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Nodus Naam:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9876,52 +9948,141 @@ msgid "Detect new changes"
msgstr "Skep Nuwe"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Verander Skikking Waarde-Soort"
+msgid "Stage all changes"
+msgstr "Plaaslike veranderinge word gebêre..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Plaaslike veranderinge word gebêre..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Nodus Naam:"
+msgid "Branches"
+msgstr "Passendes:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Skrap"
+msgid "Create New Branch"
+msgstr "Skep Nuwe"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Verwyder Anim Baan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Skaal Seleksie"
+msgid "Remotes"
+msgstr "Verwyder"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Vervang Alles"
+msgid "Create New Remote"
+msgstr "Skep Nuwe"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Verwyder Seleksie"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Nodus Naam:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Verwyder"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Nodus Naam:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Skrap"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Voorskou:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Wysig Nodus Kurwe"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12516,6 +12677,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13377,6 +13539,39 @@ msgstr "Verfris"
msgid "Edit Member"
msgstr "Lede"
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animasie Zoem."
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13389,6 +13584,82 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Skep Vouer"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Geldige karakters:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13405,6 +13676,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Maak Funksie"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Herskaleer Skikking"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13414,6 +13699,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13422,6 +13711,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Skrap"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Skep Vouer"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Anim Dupliseer Sleutels"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13431,13 +13775,70 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Alle Seleksie"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Deursoek Hulp"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Skuif Byvoeg Sleutel"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Seine"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Seine"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -14024,7 +14425,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14237,7 +14647,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 406f882df8..37c6d1943e 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -34,7 +34,7 @@
# Ahmed Shahwan <dev.ahmed.shahwan@gmail.com>, 2019.
# hshw <shw@tutanota.com>, 2020.
# Youssef Harmal <the.coder.crab@gmail.com>, 2020.
-# Nabeel20 <nabeelandnizam@gmail.com>, 2020, 2021.
+# Nabeel20 <nabeelandnizam@gmail.com>, 2020, 2021, 2022.
# merouche djallal <kbordora@gmail.com>, 2020.
# Airbus5717 <Abdussamadf350@gmail.com>, 2020.
# tamsamani mohamed <tamsmoha@gmail.com>, 2020.
@@ -56,14 +56,14 @@
# Hafid Talbi <atalbiie@gmail.com>, 2021.
# Hareth Mohammed <harethpy@gmail.com>, 2021.
# Mohammed Mubarak <modymu9@gmail.com>, 2021.
-# Spirit <i8bou3@gmail.com>, 2021.
+# Spirit <i8bou3@gmail.com>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-01-03 03:54+0000\n"
-"Last-Translator: HASSAN GAMER - حسن جيمر <gamerhassan55@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -413,6 +413,7 @@ msgstr "أنشئ %d مسارات جديدة Ùˆ أدخل Ù…ÙØ§ØªÙŠØ­ØŸ"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -877,6 +878,7 @@ msgstr "أضÙ"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -926,8 +928,7 @@ msgstr "إشارة غير قادر على الاتصال"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1985,7 +1986,6 @@ msgid "New Folder..."
msgstr "مجلد جديد..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "تحديث"
@@ -2102,7 +2102,8 @@ msgstr "الوجهات ÙˆØ§Ù„Ù…Ù„ÙØ§Øª:"
msgid "Preview:"
msgstr "إستعراض:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "الملÙ:"
@@ -2279,7 +2280,7 @@ msgstr "دالة"
msgid "Signal"
msgstr "الإشاراة"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "ثابت"
@@ -2310,6 +2311,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "تحديد %s"
@@ -2387,7 +2390,7 @@ msgstr "أعلى"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
-msgstr "عقدة"
+msgstr "وحدة"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
@@ -2895,7 +2898,7 @@ msgstr "مسح المخطط"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr "Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+msgstr "Ø§ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/editor_node.cpp editor/editor_resource_picker.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
@@ -3062,8 +3065,9 @@ msgid "Install Android Build Template..."
msgstr "تحميل قالب البناء للأندرويد..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "ÙØªØ­ مجلد بيانات المشروع"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "ÙØªØ­ مجلّد بيانات المحرّر"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3222,10 +3226,6 @@ msgid "Toggle Fullscreen"
msgstr "ØªÙØ¹ÙŠÙ„/إلغاء وضع الشاشة الكاملة"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "إظهار/Ø¥Ø®ÙØ§Ø¡ وحدة التحكم بالنظام"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "ÙØªØ­ مجلّد بيانات/إعدادات المحرّر"
@@ -3457,6 +3457,7 @@ msgid "Load Errors"
msgstr "خطأ تحميل"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "حدد"
@@ -3535,7 +3536,6 @@ msgid "Author"
msgstr "المالك"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "الحالة"
@@ -3775,6 +3775,12 @@ msgstr "المسار للمشهد:"
msgid "Import From Node:"
msgstr "إستيراد من عقدة:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "خطأ"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Ø§ÙØªØ­ المجلد الحاوي هذه القوالب."
@@ -4680,6 +4686,7 @@ msgid "Subfolder:"
msgstr "المجلد Ø§Ù„ÙØ±Ø¹ÙŠ:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "المالك:"
@@ -6395,6 +6402,7 @@ msgid "Zoom to 1600%"
msgstr "التكبير حتى 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "أض٠%s"
@@ -9883,7 +9891,8 @@ msgid "TileSet"
msgstr "Ù…ÙØ­Ø¯Ø¯ البلاط"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "لا يوجد Ø¥Ø¶Ø§ÙØ§Øª VCS Ù…ØªÙˆØ§ÙØ±Ø©."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9891,16 +9900,56 @@ msgid "Error"
msgstr "خطأ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "لم يتم Ø¥Ø¶Ø§ÙØ© Ù…Ù„ÙØ§Øª إلى المرحلة"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "لا أسم Ù…Ùقدم."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "ارتكاب"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "لم يتم تهيئة Ø¥Ø¶Ø§ÙØ§Øª VCS"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "تغيرات Ø§Ù„Ù…ÙØ¸Ù„Ù„"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "تغيرات Ø§Ù„Ù…ÙØ¸Ù„Ù„"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "ارتكاب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "الشجرة Ø§Ù„ÙØ±Ø¹ÙŠØ©"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "هل أنت واثق من ÙØªØ­ أكثر من مشروع؟"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "طَبق إعادة تعيين"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9911,16 +9960,148 @@ msgid "Initialize"
msgstr "الشروع"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "حيز التدريج"
+#, fuzzy
+msgid "Remote Login"
+msgstr "مسح النقطة"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "إعادة التسمية"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "الكش٠عن التغيرات الجديدة"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "التغيرات"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "الإغلاق مع Ø­ÙØ¸ التعديلات؟"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "جاري تخزين التعديلات المحلية..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "ØªÙØºÙŠØ±Ø§Øª المادة"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "اقترا٠التعديلا"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "اقترا٠التعديلا"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "ارتكاب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "يطابق:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "إنشاء مشروع جديد"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "حذ٠مسار التحريك"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "عن بعد"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "إنشاء مشروع جديد"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "إزالة عنصر"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "من بعد "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "من بعد "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "الميش المصدر:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9939,28 +10120,23 @@ msgid "Typechange"
msgstr "تعديل النوع"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Ø­ÙØ¯Ø¯Øª المرحلة"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Ù…ÙØ¬Ù…Ù„ المراحل"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "اقترا٠التعديلا"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "إظهار آخر تعديلات المل٠قبل قبولهم ÙÙŠ آخر نسخة"
+#, fuzzy
+msgid "View:"
+msgstr "أظهر"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "لا Ù…Ù„Ù ÙØ±ÙˆÙ‚ نشط"
+#, fuzzy
+msgid "Split"
+msgstr "ÙØµÙ„ المسار"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "الكش٠عن التغييرات ÙÙŠ Ù…Ù„Ù Ø§Ù„ÙØ±ÙˆÙ‚"
+#, fuzzy
+msgid "Unified"
+msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12666,6 +12842,7 @@ msgid "Export list to a CSV file"
msgstr "تصدير القائمة إلى مل٠CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "مسار المورد"
@@ -13524,6 +13701,40 @@ msgstr "تحديث الرسم البياني"
msgid "Edit Member"
msgstr "تعديل العضو"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "تحديد التعبير"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "رسوم متحركة"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "نوع الإدخال غير متوقع: "
@@ -13536,6 +13747,88 @@ msgstr "أصبح المÙكرر غير صالحاً"
msgid "Iterator became invalid: "
msgstr "أصبح المÙكرر غير صالحاً: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "إعادة تسمية مجلد:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "حدّة"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "نوع:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "ذاتي"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "عند الحر٠%s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "أض٠%s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "تحديد %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "أض٠%s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "جلب %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "اسم خاصية المؤشر index property غير صالح."
@@ -13552,6 +13845,21 @@ msgstr "لا يؤدي المسار للوصول لعÙقدة!"
msgid "Invalid index property name '%s' in node %s."
msgstr "اسم خاصية المؤشر \"الÙهرس\" '%s' ÙÙŠ العÙقدة %s غير صالح."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "تحديد %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "الوظائ٠البرمجية"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "تغيير حجم المصÙÙˆÙØ©"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": معامل النوع غير صحيح: "
@@ -13561,6 +13869,10 @@ msgid ": Invalid arguments: "
msgstr ": معاملات غير صالحة: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "لم يتم إيجاد VariableGet ÙÙŠ النص البرمجي: "
@@ -13569,6 +13881,66 @@ msgid "VariableSet not found in script: "
msgstr "لم يتم إيجاد (Ù…ÙØ­Ø¯Ø¯ Ø§Ù„Ù…ÙØªØºÙŠØ±) VariableSet ÙÙŠ النص البرمجي: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "إعادة تحميل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "ترتيبية المحور Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "ترتيبية المحور Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "تمكين نمط البرمجة Singleton ل GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "عقدة التنقل الزمني"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "تعديل شجرة المشهد"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "ذاتي"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "قص العÙقد"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "العقدة المخصصة لا تحتوي طريقة ()step_ ، لا يمكن معالجة الشكل البياني."
@@ -13580,13 +13952,75 @@ msgstr ""
"القيمة Ø§Ù„Ù…ÙØ±Ø¬Ø¹Ø© من _step() غير صالحة، ينبغي أن تكون رقماً (تسلسل)ØŒ أو نصاً "
"(خطأ)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "إستدعاءات"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ثوابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "استخدام الحيّز المحلي"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "استخدام الحيّز المحلي"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "إجراء"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "بحث VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "جلب %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "تحريك الإطار"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "نسبة الإطار الÙيزيائي %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "الإشاراة"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "الإشاراة"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "كائن"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14265,16 +14699,26 @@ msgstr ""
"خلÙية-المنظر ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"لا يدعم برنامج تشغيل الÙيديو GLES2 الجسيمات القائمة على وحدة معالجة الرسومات "
"(GPU-based particles).\n"
"استخدم عقدة جسيمات-وحدة-المعالجة-المركزية-ثنائية-Ø§Ù„Ø¨ÙØ¹Ø¯ (CPUParticles2D) بدلاً "
"من ذلك. يمكنك استخدام خيار \"التحويل إلى CPUParticles\" لهذا الغرض."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14541,10 +14985,11 @@ msgid "Only uniform scales are supported."
msgstr "المعايير الموحدة هي المدعومة Ùقط."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"الجسيمات القائمة على وحدة معالجة الرسومات (GPU-based particles) لا تدعم "
"برنامج تشغيل الÙيديو GLES2 .\n"
@@ -14553,6 +14998,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "لا يوجد شيء مرئي لأن المجسمات لم يتم تعيين لها رسم التمريرات."
diff --git a/editor/translations/az.po b/editor/translations/az.po
index bc7f45ca0f..5aecfb0e5f 100644
--- a/editor/translations/az.po
+++ b/editor/translations/az.po
@@ -379,6 +379,7 @@ msgstr "%d YENİ izlər yarat və açarları daxil et?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -861,6 +862,7 @@ msgstr "ÆlavÉ™ Et"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -912,8 +914,7 @@ msgstr "Siqnala baÄŸlana bilmir"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1963,7 +1964,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2080,7 +2080,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2248,7 +2249,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2278,6 +2279,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2974,7 +2977,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3109,10 +3112,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3330,6 +3329,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3407,7 +3407,6 @@ msgid "Author"
msgstr "Müəlliflər"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3634,6 +3633,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4494,6 +4498,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6148,6 +6153,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9441,7 +9447,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9449,7 +9455,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9457,10 +9468,41 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Dəyişdir"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Æminsinizmi ki, bütün É™laqÉ™lÉ™ri bu siqnaldan çıxartmaq istÉ™yirsiniz?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Sıfırla"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9469,39 +9511,56 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Səhv açarları sil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Username"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH private key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9509,15 +9568,114 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "UyÄŸunlaÅŸmalar:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Yeni %s yarat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Animasya İzini Sil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Remotes"
+msgstr "Sil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Yeni %s yarat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Sil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Sil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12028,6 +12186,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12859,6 +13018,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animasiyanı Təmizləmə"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12871,6 +13063,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12887,6 +13153,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funksiyalar:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Massiv Ölçüsünü Dəyiş"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12896,6 +13176,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12904,6 +13188,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Açar sözü buraya daxil edin"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12913,12 +13246,66 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Funksiyalar:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Siqnal:"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13480,7 +13867,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13693,7 +14089,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 03d385bf53..a0e22270a6 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -372,6 +372,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -821,6 +822,7 @@ msgstr "ДобавÑне"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -870,8 +872,7 @@ msgstr "Сигналът не може да бъде Ñвързан"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1897,7 +1898,6 @@ msgid "New Folder..."
msgstr "Ðова папка..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2014,7 +2014,8 @@ msgstr "Папки и файлове:"
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Файл:"
@@ -2184,7 +2185,7 @@ msgstr "Метод"
msgid "Signal"
msgstr "Сигнал"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "КонÑтанта"
@@ -2215,6 +2216,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2933,7 +2936,8 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
msgstr "ОтварÑне на папката Ñ Ð´Ð°Ð½Ð½Ð¸ на проекта"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3070,10 +3074,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Превключване на ÑиÑтемната конзола"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "ОтварÑне на папката Ñ Ð´Ð°Ð½Ð½Ð¸/наÑтройки на редактора"
@@ -3294,6 +3294,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3370,7 +3371,6 @@ msgid "Author"
msgstr "Ðвтор"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3595,6 +3595,12 @@ msgstr "Път на Ñцената:"
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Грешка!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4452,6 +4458,7 @@ msgid "Subfolder:"
msgstr "Подпапка:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6129,6 +6136,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "ДобавÑне на %s"
@@ -9459,7 +9467,7 @@ msgid "TileSet"
msgstr "Плочен набор"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9467,7 +9475,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9475,7 +9488,38 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Промени в шейдъра:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Промени в шейдъра:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Поддърво"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9487,7 +9531,37 @@ msgid "Initialize"
msgstr "Инициализиране"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Премахване на точката"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Преименуван"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9495,49 +9569,140 @@ msgid "Detect new changes"
msgstr "ЗаÑичане на новите промени"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "ЗатвÑране и запазване на промените?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Запазване на локалните промени..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Промени в материала:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
-msgstr "Преименуван"
+msgid "Commit List"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
-msgstr "Изтрит"
+msgid "Commit list size"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "СъвпадениÑ:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Покажи СелекциÑта (вмеÑти в Ñ†ÐµÐ»Ð¸Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€ÐµÑ†)"
+msgid "Create New Branch"
+msgstr "Създаване на нов проект"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Запази Ð’Ñичко"
+msgid "Remove Branch"
+msgstr "Премахване на проекта"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Отдалечен"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Създаване на нов проект"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Премахване на текÑтурата"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Отдалечено "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Отдалечено "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Източник за полигонна мрежа:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr "Преименуван"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Изтрит"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "View:"
+msgstr "Преглед"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12056,6 +12221,7 @@ msgid "Export list to a CSV file"
msgstr "ИзнаÑÑне на ÑпиÑъка като файл CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12896,6 +13062,40 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Задаване на израз"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "анимациÑ"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12908,6 +13108,84 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Папка:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Типове:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "ДобавÑне на %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "ДобавÑне на %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12924,6 +13202,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Функции"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "ПреоразмерÑване на маÑива"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12933,6 +13225,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12941,6 +13237,64 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Презареждане"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ð¾ Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Ðов корен на Ñцената"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Редактиране на дървото на Ñцената"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "ИзрÑзване на възлите"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12950,12 +13304,69 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "КонÑтанти"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ДейÑтвие"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "ТърÑене във VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "ПремеÑтване на кадъра"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13553,7 +13964,16 @@ msgstr "ParallaxLayer работи Ñамо, когато е наÑледник
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13775,7 +14195,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index a5f504af97..6af9541a8e 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -366,6 +366,7 @@ msgstr "%d à¦à¦° জনà§à¦¯ নতà§à¦¨ টà§à¦°à§à¦¯à¦¾à¦•/পথ-সমà
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -846,6 +847,7 @@ msgstr "সংযোজন করà§à¦¨"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -898,8 +900,7 @@ msgstr "সংযোজক সংকেত/সিগনà§à¦¯à¦¾à¦²:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2021,7 +2022,6 @@ msgid "New Folder..."
msgstr "ফোলà§à¦¡à¦¾à¦° তৈরি করà§à¦¨"
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "রিফà§à¦°à§‡à¦¸ করà§à¦¨"
@@ -2146,7 +2146,8 @@ msgstr "পথ à¦à¦¬à¦‚ ফাইল:"
msgid "Preview:"
msgstr "পà§à¦°à¦¿à¦­à¦¿à¦‰:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "ফাইল:"
@@ -2349,7 +2350,7 @@ msgstr "মেথডের তালিকা:"
msgid "Signal"
msgstr "সংকেতসমূহ"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
@@ -2382,6 +2383,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3157,7 +3160,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "পà§à¦°à¦•লà§à¦ª মà§à¦¯à¦¾à¦¨à§‡à¦œà¦¾à¦°"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3325,11 +3328,6 @@ msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦
#: editor/editor_node.cpp
#, fuzzy
-msgid "Toggle System Console"
-msgstr "CanvasItem দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾ টগল করà§à¦¨"
-
-#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস"
@@ -3567,6 +3565,7 @@ msgid "Load Errors"
msgstr "ভà§à¦²/সমসà§à¦¯à¦¾-সমূহ লোড করà§à¦¨"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨"
@@ -3658,7 +3657,6 @@ msgid "Author"
msgstr "লেখক"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
#, fuzzy
msgid "Status"
@@ -3908,6 +3906,12 @@ msgstr "দৃশà§à¦¯à§‡à¦° পথ:"
msgid "Import From Node:"
msgstr "নোড হতে ইমà§à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "সমসà§à¦¯à¦¾/ভà§à¦²"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4891,6 +4895,7 @@ msgid "Subfolder:"
msgstr "উপফোলà§à¦¡à¦¾à¦°:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "লেখক:"
@@ -6725,6 +6730,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨"
@@ -10406,7 +10412,7 @@ msgid "TileSet"
msgstr "TileSet (টাইল-সেট)..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10414,19 +10420,58 @@ msgid "Error"
msgstr "সমসà§à¦¯à¦¾/ভà§à¦²"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨ অথবা সরান..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "à¦à¦•ধিক পà§à¦°à¦•লà§à¦ª খোলায় আপনি সà§à¦¨à¦¿à¦¶à§à¦šà¦¿à¦¤?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "সমà§à¦ªà§à¦°à¦¸à¦¾à¦°à¦¨/সংকোচন অপসারণ করà§à¦¨ (রিসেট জà§à¦®à§)"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -10436,7 +10481,37 @@ msgid "Initialize"
msgstr "বড় হাতের অকà§à¦·à¦°à§‡ পরিবরà§à¦¤à¦¨à§‡ করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "পথের বিনà§à¦¦à§ অপসারণ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10446,54 +10521,146 @@ msgstr "নতà§à¦¨ তৈরি করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨"
+msgid "Discard all changes"
+msgstr "বনà§à¦§ à¦à¦¬à¦‚ পরিবরà§à¦¤à¦¨ সংরকà§à¦·à¦£ করবেন?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "সà§à¦¥à¦¾à¦¨à§€à§Ÿ পরিবরà§à¦¤à¦¨-সমূহ সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "কমিউনিটি/যৌথ-সামাজিক উৎস"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
+msgid "Branches"
+msgstr "মিলসমূহ:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
+msgid "Create New Branch"
+msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª তৈরি করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨ (Anim) টà§à¦°à§à¦¯à¦¾à¦• রিমà§à¦­ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
msgstr "অপসারণ করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨"
+msgid "Create New Remote"
+msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª তৈরি করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ সমূহ অপসারণ করà§à¦¨"
+msgid "Remove Remote"
+msgstr "বসà§à¦¤à§ অপসারণ করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "সকলà§à¦—à§à¦²à¦¿ সংরকà§à¦·à¦£ করà§à¦¨"
+msgid "Remote Name"
+msgstr "অপসারণ করà§à¦¨"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡à¦° পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ সà§à¦¸à¦‚গত/সমনà§à¦¬à§Ÿ করà§à¦¨"
+msgid "Remote URL"
+msgstr "অপসারণ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "No file diff is active"
-msgstr "কোনো ফাইল নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ হয়নি!"
+msgid "Force Push"
+msgstr "উৎস Mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "অপসারণ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "দৃশà§à¦¯/পরিদরà§à¦¶à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "পথ বিভকà§à¦¤ করà§à¦¨"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -13263,6 +13430,7 @@ msgid "Export list to a CSV file"
msgstr "পà§à¦°à¦•লà§à¦ª à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "রিসোরà§à¦¸-à¦à¦° পথ"
@@ -14209,6 +14377,40 @@ msgstr "রিফà§à¦°à§‡à¦¸ করà§à¦¨"
msgid "Edit Member"
msgstr "সদসà§à¦¯à¦—ণ (Members):"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "অভিবà§à¦¯à¦•à§à¦¤à¦¿ (Expression) পরিবরà§à¦¤à¦¨ করà§à¦¨"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "যোগান/ইনপà§à¦Ÿ-à¦à¦° ধরণ পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦¿à¦®à§‚লক নয়: "
@@ -14221,6 +14423,87 @@ msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦•ারী অকারà§à¦¯à¦•র হà
msgid "Iterator became invalid: "
msgstr "পà§à¦¨à¦°à¦¾à¦¬à§ƒà¦¤à§à¦¤à¦•ারী অকারà§à¦¯à¦•র হয়ে পড়েছে: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "নোড পà§à¦¨à¦ƒà¦¨à¦¾à¦®à¦•রণ করà§à¦¨"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "পিচà§â€Œ"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "ধরণ:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "সà§à¦¬à§€à¦¯à¦¼"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "গà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ অকà§à¦·à¦°à¦¸à¦®à§‚হ:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "%s সংযà§à¦•à§à¦¤ করà§à¦¨"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "সূচক/ইনডেকà§à¦¸ মানের অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম।"
@@ -14237,6 +14520,20 @@ msgstr "পথটি নোডকে দিকনিরà§à¦¦à§‡à¦¶ করে à¦
msgid "Invalid index property name '%s' in node %s."
msgstr "%s নোডে সূচক/ইনডেকà§à¦¸ মানের অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম '%s'।"
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "ফাংশনগà§à¦²à¦¿:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "শà§à¦°à§‡à¦£à§€à¦¬à¦¿à¦¨à§à¦¯à¦¾à¦¸/সারি পà§à¦¨à¦°à§à¦®à¦¾à¦ªà¦¨ করà§à¦¨"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান/আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ-à¦à¦° ধরণ: "
@@ -14246,6 +14543,10 @@ msgid ": Invalid arguments: "
msgstr ": অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান/আরà§à¦—à§à¦®à§‡à¦¨à§à¦Ÿ-সমূহ: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-পà§à¦°à¦¾à¦ªà¦• (VariableGet) পাওয়া যায়নি: "
@@ -14254,6 +14555,65 @@ msgid "VariableSet not found in script: "
msgstr "সà§à¦•à§à¦°à¦¿à¦ªà§à¦Ÿà§‡ চলক-সà§à¦¥à¦¾à¦ªà¦• (VariableSet) পাওয়া যায়নি: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "রিলোড"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "ইনà§à¦¡à§‡à¦•à§à¦¸:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "ইনà§à¦¡à§‡à¦•à§à¦¸:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "ধà§à¦°à§à¦¬à¦•/কনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "টাইম-সীকà§â€Œ নোড"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "দৃশà§à¦¯à§‡à¦° শাখা (নোডসমূহ):"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "সà§à¦¬à§€à¦¯à¦¼"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "নোড-সমূহ করà§à¦¤à¦¨/কাট করà§à¦¨"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "সà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ (custom) নোডে কোনো _step() মেথড নেই, গà§à¦°à¦¾à¦« পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾à¦•রণ অসমà§à¦­à¦¬à¥¤"
@@ -14265,15 +14625,77 @@ msgstr ""
"_step() হতে অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মান ফেরৎ à¦à¦¸à§‡à¦›à§‡, মান অবশà§à¦¯à¦‡ পূরà§à¦£à¦¸à¦‚খà§à¦¯à¦¾ (integer) (কà§à¦°à¦®à¦¿à¦•), "
"অথবা শবà§à¦¦à¦®à¦¾à¦²à¦¾/বাকà§à¦¯ (string) (ভà§à¦²/সমসà§à¦¯à¦¾) হতে হবে।"
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "ডাকà§à¦¨ (Call)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ধà§à¦°à§à¦¬à¦•সমূহ:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "মাপের মোড করà§à¦¨ (R)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "মাপের মোড করà§à¦¨ (R)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "পà§à¦°à¦•à§à¦°à¦¿à¦¯à¦¼à¦¾/অà§à¦¯à¦¾à¦•শন"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Shader Graph Node অপসারণ করà§à¦¨"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "ফà§à¦°à§‡à¦® পà§à¦°à¦¤à¦¿à¦²à§‡à¦ªà¦¨ করà§à¦¨"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "সà§à¦¥à¦¿à¦°/বদà§à¦§ ফà§à¦°à§‡à¦® %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "সংকেতসমূহ"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "সংকেতসমূহ"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "ইনসà§à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14889,7 +15311,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -15126,7 +15557,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/br.po b/editor/translations/br.po
index e7990afc1f..77c78f55b8 100644
--- a/editor/translations/br.po
+++ b/editor/translations/br.po
@@ -360,6 +360,7 @@ msgstr "Krouiñ %d roudenn NEVEZ hag enlakaat alc'hwezioù ?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -823,6 +824,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -872,8 +874,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1897,7 +1898,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2014,7 +2014,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2182,7 +2183,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2212,6 +2213,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2906,7 +2909,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3041,10 +3044,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3262,6 +3261,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3338,7 +3338,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3564,6 +3563,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4419,6 +4423,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6067,6 +6072,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9351,7 +9357,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9359,7 +9365,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9367,7 +9378,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9379,39 +9418,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9419,15 +9474,108 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Dilemel ar Roudenn Fiñvskeudenn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "View:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11936,6 +12084,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12765,6 +12914,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Tro Fiñvskeudenn"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12777,6 +12959,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12793,6 +13049,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Fonksionoù :"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12802,6 +13071,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12810,6 +13083,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Enlakaat an Alc'hwezh Amañ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12819,12 +13141,65 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Fonksionoù :"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13386,7 +13761,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13599,7 +13983,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 043bc573f0..15c6342076 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -6,7 +6,7 @@
# Javier Ocampos <xavier.ocampos@gmail.com>, 2018.
# Roger Blanco Ribera <roger.blancoribera@gmail.com>, 2016-2018, 2020.
# Rubén Moreno <ruben.moreno.romero@gmail.com>, 2018.
-# roger <616steam@gmail.com>, 2019, 2020, 2021.
+# roger <616steam@gmail.com>, 2019, 2020, 2021, 2022.
# Roger BR <drai_kin@hotmail.com>, 2019.
# Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2020.
# Xavier Gomez <hiulit@gmail.com>, 2020, 2021.
@@ -21,7 +21,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-20 18:53+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: roger <616steam@gmail.com>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/"
"godot/ca/>\n"
@@ -30,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.10\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -371,6 +371,7 @@ msgstr "Voleu crear %d NOVES pistes i inserir-hi claus?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -842,6 +843,7 @@ msgstr "Afegeix"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -893,8 +895,7 @@ msgstr "No es pot connectar el senyal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1510,7 +1511,7 @@ msgstr "Nom no vàlid."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "No pot començar amb un digit."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1982,7 +1983,6 @@ msgid "New Folder..."
msgstr "Nou Directori..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Refresca"
@@ -2099,7 +2099,8 @@ msgstr "Directoris i Fitxers:"
msgid "Preview:"
msgstr "Vista prèvia:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fitxer:"
@@ -2278,7 +2279,7 @@ msgstr "Mètode"
msgid "Signal"
msgstr "Senyal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constant"
@@ -2309,6 +2310,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Definir %s"
@@ -3071,8 +3074,9 @@ msgid "Install Android Build Template..."
msgstr "Instal·lar Plantilla de Compilació d'Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Obre el directori de Dades del Projecte"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Obre el directori de Dades de l'Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3236,10 +3240,6 @@ msgid "Toggle Fullscreen"
msgstr "Mode Pantalla Completa"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Commutar la consola del sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Obre el directori de Dades/Configuració de l'Editor"
@@ -3470,6 +3470,7 @@ msgid "Load Errors"
msgstr "Errors de Càrrega"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Selecciona"
@@ -3550,7 +3551,6 @@ msgid "Author"
msgstr "Autors"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Estat"
@@ -3792,6 +3792,12 @@ msgstr "Camí de l'Escena:"
msgid "Import From Node:"
msgstr "Importa des del Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Error"
+
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Open the folder containing these templates."
@@ -4000,6 +4006,7 @@ msgstr "Obrir Fitxer"
#: editor/export_template_manager.cpp
msgid "Open the folder containing installed templates for the current version."
msgstr ""
+"Obre la carpeta que conté les plantilles instal·lades per la versió actual."
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -4033,6 +4040,8 @@ msgid ""
"Download and install templates for the current version from the best "
"possible mirror."
msgstr ""
+"Descarrega i instal·la plantilles per a la versió actual des del millor "
+"mirall possible."
#: editor/export_template_manager.cpp
msgid "Official export templates aren't available for development builds."
@@ -4084,6 +4093,8 @@ msgid ""
"The templates will continue to download.\n"
"You may experience a short editor freeze when they finish."
msgstr ""
+"Les plantilles continuaran descarregant-se.\n"
+"Es possible que experimenteu una breu congelació de l'editor quan acabin."
#: editor/filesystem_dock.cpp
msgid "Favorites"
@@ -4719,6 +4730,7 @@ msgid "Subfolder:"
msgstr "Subcarpeta:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -5671,8 +5683,9 @@ msgid "All"
msgstr "Tot"
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Search templates, projects, and demos"
-msgstr ""
+msgstr "Buscar plantilles, projectes i demos."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Search assets (excluding templates, projects, and demos)"
@@ -6460,6 +6473,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom a 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Afegeix %s"
@@ -9964,7 +9978,8 @@ msgid "TileSet"
msgstr "Conjunt de rajoles"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "No hi ha addons VCS disponibles."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9972,8 +9987,14 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "No hi ha fitxers afegits a l'escenari"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "No s'ha proporcionat cap nom."
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -9982,8 +10003,41 @@ msgstr "Comunitat"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "VCS Addon is not initialized"
-msgstr "L'Addon VCS no està inicialitzat"
+msgid "Staged Changes"
+msgstr "Canvis de Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Canvis de Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Comunitat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subarbre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Esteu segur que voleu obrir més d'un projecte de cop?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Resetejar"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9995,16 +10049,149 @@ msgid "Initialize"
msgstr "Converteix a Majúscules"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Zona de posada en escena"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Elimina Punt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Reanomena"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detectar nous canvis"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Canvis"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Tancar i desar els canvis?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Emmagatzemant canvis locals..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Canvis de Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Sincronitzar Canvis en Scripts"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Sincronitzar Canvis en Scripts"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Comunitat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Coincidències:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Crea un Projecte nou"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Treu la Pista"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remot"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Crea un Projecte nou"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Elimina Element"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remot "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remot "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Malla d'Origen:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -10026,33 +10213,23 @@ msgid "Typechange"
msgstr "Modifica"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "Stage Selected"
-msgstr "Elimina Seleccionats"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Desa-ho Tot"
+msgid "View:"
+msgstr "Vista"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Sincronitzar Canvis en Scripts"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Verifica les diferències entre fitxers abans de publicar-les a la darrera "
-"versió"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "No hi ha cap diferència de fitxer activa"
+msgid "Split"
+msgstr "Parteix el Camí"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detecta els canvis en el fitxer"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificat"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12837,6 +13014,7 @@ msgid "Export list to a CSV file"
msgstr "Exportar Perfil"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Camí de Recursos"
@@ -13735,6 +13913,40 @@ msgstr "Refresca"
msgid "Edit Member"
msgstr "Editar Membre"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Canviar Expressió"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animació"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tipus d'entrada no iterable: "
@@ -13747,6 +13959,88 @@ msgstr "L'Iterador ja no és vàlid"
msgid "Iterator became invalid: "
msgstr "L'Iterador ja no és vàlid: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Reanomenant directori:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "commutador:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipus:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Propi"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Al caràcter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Afegeix %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Definir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Afegeix %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Obtenir %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "El Nom de la propietat índex no és vàlid."
@@ -13763,6 +14057,21 @@ msgstr "El camí no condueix a cap Node!"
msgid "Invalid index property name '%s' in node %s."
msgstr "El nom de la propietat índex '%s' del node %s no és vàlid ."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Definir %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funcions"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensiona la Matriu"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argument no vàlid del tipus: "
@@ -13772,6 +14081,10 @@ msgid ": Invalid arguments: "
msgstr ": Arguments no vàlids: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Variable Get no trobada en l'Script: "
@@ -13780,6 +14093,66 @@ msgid "VariableSet not found in script: "
msgstr "Variable Set no trobada en l'Script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Torna a Carregar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ãndex"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ãndex"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Habilitar Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Node cercaTemps"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edició de l'arbre d'escenes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Propi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Talla els Nodes"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"El node personalitzat no té cap mètode _step(), no es pot processar el graf."
@@ -13792,14 +14165,76 @@ msgstr ""
"El Valor retornat per _step() no és vàlid. Ha de ser un nombre enter (seq "
"out), o una cadena de text (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Crides"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constants"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Utilitzar Espai Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Utilitzar Espai Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Acció"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Elimina el Node de VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Obtenir %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Enganxa el Fotograma"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fotograma de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Senyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Senyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instància"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14447,7 +14882,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14710,7 +15154,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index eba90c7fe3..24933836f4 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -386,6 +386,7 @@ msgstr "VytvoÅ™it %d NOVÃCH stop a vložit klíÄe?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -855,6 +856,7 @@ msgstr "Přidat"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -904,8 +906,7 @@ msgstr "Připojit Signál"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1964,7 +1965,6 @@ msgid "New Folder..."
msgstr "Nová složka..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Obnovit"
@@ -2081,7 +2081,8 @@ msgstr "Složky a soubory:"
msgid "Preview:"
msgstr "Náhled:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Soubor:"
@@ -2256,7 +2257,7 @@ msgstr "Metoda"
msgid "Signal"
msgstr "Signál"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstantní"
@@ -2287,6 +2288,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Nastav %s"
@@ -3037,8 +3040,9 @@ msgid "Install Android Build Template..."
msgstr "Nainstalovat kompilaÄní Å¡ablonu pro Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Otevřít složku s daty projektu"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Otevřít složku s daty editoru"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3194,10 +3198,6 @@ msgid "Toggle Fullscreen"
msgstr "Přepnout celou obrazovku"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Zapnout/Vypnout systémovou konzoli"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Otevřít složku s daty a nastavením editoru"
@@ -3427,6 +3427,7 @@ msgid "Load Errors"
msgstr "NaÄíst chyby"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Vybrat"
@@ -3503,7 +3504,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3747,6 +3747,12 @@ msgstr "Cesta ke scéně:"
msgid "Import From Node:"
msgstr "Import z uzlu:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Chyba"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Otevřít složku obsahující tyto šablony."
@@ -4632,6 +4638,7 @@ msgid "Subfolder:"
msgstr "Podsložka:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6323,6 +6330,7 @@ msgid "Zoom to 1600%"
msgstr "Přiblížení na 1600 %"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Přidat %s"
@@ -9727,7 +9735,8 @@ msgid "TileSet"
msgstr "TileSet (Sada dlaždic)"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "K dispozici nejsou žádná VCS rozšíření."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9735,16 +9744,56 @@ msgid "Error"
msgstr "Chyba"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Zádné soubory nebyly přidány k zápisu"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nebylo poskytnuto žádné jméno."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS rozšíření nejní inicializováno"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Změny shaderu:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Změny shaderu:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Podstrom"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Jste si jisti, že chcete otevřit více než jeden projekt?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Resetovat"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9755,16 +9804,148 @@ msgid "Initialize"
msgstr "Inicializovat"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "K zápsání"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Odstranit bod"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Přejmenovat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detekovat nové změny"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Změny"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Zavřít a uložit změny?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Ukládám lokální změny..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Změny materiálu:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commitnout změny"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commitnout změny"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Shody:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Vytvořit nový projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Odstranit stopu animace"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Vzdálený"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Vytvořit nový projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Odstranit položku"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Vzdálený "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Vzdálený "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Zdrojová mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9783,28 +9964,23 @@ msgid "Typechange"
msgstr "Změnit typ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Připravit vybrané k zapsání"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Připravit k zapsání vše"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commitnout změny"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Podívat se na rozdíly, než se commitnou jako nejnovější verze"
+#, fuzzy
+msgid "View:"
+msgstr "Zobrazení"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Žádné aktivní porovnání změn"
+#, fuzzy
+msgid "Split"
+msgstr "Rozdělit cestu"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Zjistit změny v souborech"
+#, fuzzy
+msgid "Unified"
+msgstr "Úpravy"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12474,6 +12650,7 @@ msgid "Export list to a CSV file"
msgstr "Exportovat seznam do CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Cesta ke zdroji"
@@ -13322,6 +13499,40 @@ msgstr "Obnovit graf"
msgid "Edit Member"
msgstr "Upravit Äleny"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Nastavit výraz"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animace"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Vstupním typem nelze iterovat: "
@@ -13334,6 +13545,88 @@ msgstr "Iterátor se stal neplatným"
msgid "Iterator became invalid: "
msgstr "Iterátor se stal neplatným: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Přejmenování složky:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Stoupání:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Typy:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Tento objekt"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Na znaku %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Přidat %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Nastav %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Přidat %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Přijmi %d"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Neplatné jméno vlastnosti."
@@ -13350,6 +13643,21 @@ msgstr "Cesta nevede k uzlu!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Neplatné jméno vlastnosti '%s' v uzlu %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Nastav %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkce"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Změnit velikost pole"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Neplatný argument typu: "
@@ -13359,6 +13667,10 @@ msgid ": Invalid arguments: "
msgstr ": Neplatné argumenty: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Proměnná pro získání nebyla ve skriptu nalezena: "
@@ -13367,6 +13679,66 @@ msgid "VariableSet not found in script: "
msgstr "Proměnná pro nastavení nebyla ve skriptu nalezena: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Znovu naÄíst"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z-Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z-Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstantní"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstantní"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstantní"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstantní"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Zapnutý GDNative Singleton"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Uzel TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Úpravy stromu scény"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Tento objekt"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Vyjmout uzly"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "Vlastní uzel nemá metodu _step(), takže nelze postupovat grafem."
@@ -13378,13 +13750,75 @@ msgstr ""
"Neplatná návratová hodnota z funkce _step(). Musí být celé Äíslo (výstupní "
"posloupnost), nebo řetězec (chyba)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Volání"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanty"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Použít místní prostor"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Použít místní prostor"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Akce"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Hledat VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Přijmi %d"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Posunout snímek"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fyzikální snímek %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signál"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signál"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instance"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14010,15 +14444,25 @@ msgstr ""
"Uzel ParallaxLayer funguje pouze když je dítětem uzlu ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Grafický ovladaÄ GLES2 nepodporuje Äástice založené na GPU.\n"
"Použijte uzel CPUParticles2D. Na převod lze použít \"Převést na CPUParticles"
"\"."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14264,10 +14708,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Video driver GLES2 nepodporuje Äástice na GPU.\n"
"Místo toho použijte uzel CPUParticles. K převodu můžete použít \"Převést na "
@@ -14275,6 +14720,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Nic není viditelné, protože mřížky nebyly přiřazeny do vykreslovací fronty."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index f35a125640..94f5d4b033 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -381,6 +381,7 @@ msgstr "Opret %d NYE spor og indsæt nøgler?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -873,6 +874,7 @@ msgstr "Tilføj"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -926,8 +928,7 @@ msgstr "Kan ikke forbinde signal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2041,7 +2042,6 @@ msgid "New Folder..."
msgstr "Opret mappe..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Opdater"
@@ -2166,7 +2166,8 @@ msgstr "Mapper & Filer:"
msgid "Preview:"
msgstr "Forhåndsvisning:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fil:"
@@ -2343,7 +2344,7 @@ msgstr "Metoder"
msgid "Signal"
msgstr "Signaler"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstant"
@@ -2376,6 +2377,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3132,7 +3135,8 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
msgstr "Ã…bn Projekt datamappe"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3297,11 +3301,6 @@ msgid "Toggle Fullscreen"
msgstr "Skifter fuldskærm"
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Skifter Modus"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Åbn redaktør Data/Indstillinger-mappe"
@@ -3532,6 +3531,7 @@ msgid "Load Errors"
msgstr "Indlæs Fejl"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Vælg"
@@ -3615,7 +3615,6 @@ msgid "Author"
msgstr "Forfattere"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3849,6 +3848,12 @@ msgstr "Scene Sti:"
msgid "Import From Node:"
msgstr "Importer Fra Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Fejl!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4797,6 +4802,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Forfatter:"
@@ -6558,6 +6564,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -10092,7 +10099,7 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10100,19 +10107,58 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Intet navn angivet."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Fællesskab"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Skift Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Skift Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Fællesskab"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Er du sikker på at du vil fjerne alle forbindelser fra dette signal?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Anvende nulstilling"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -10121,7 +10167,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Fjern punkt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Omdøb"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10131,53 +10207,145 @@ msgstr "Opret Ny %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Skift"
+msgid "Discard all changes"
+msgstr "Skift Shader"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Gemmer lokale ændringer..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Skift Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Synkroniser Script Ændringer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Synkroniser Script Ændringer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Fællesskab"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Omdøb"
+msgid "Branches"
+msgstr "Matches:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Slet"
+msgid "Create New Branch"
+msgstr "Opret Ny %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Skift"
+msgid "Remove Branch"
+msgstr "Fjern Anim Spor"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Slet Valgte"
+msgid "Remotes"
+msgstr "Fjern"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Vælg alle"
+msgid "Create New Remote"
+msgstr "Opret Ny %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Synkroniser Script Ændringer"
+msgid "Remove Remote"
+msgstr "Fjern Template"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Fjern"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Fjern"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Renamed"
+msgstr "Omdøb"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Slet"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Skift"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "View:"
+msgstr "Forhåndsvisning:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Rediger Node Kurve"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12829,6 +12997,7 @@ msgid "Export list to a CSV file"
msgstr "Eksporter Projekt"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13715,6 +13884,40 @@ msgstr "Opdater"
msgid "Edit Member"
msgstr "Medlemmer"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Skift udtryk"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animation"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Input type ikke iterabel: "
@@ -13727,6 +13930,84 @@ msgstr "Iterator blev ugyldig"
msgid "Iterator became invalid: "
msgstr "Iterator blev ugyldig: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Omdøber mappe:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Basis Type:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Selv"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Gyldige karakterer:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ugyldigt index egenskabsnavn."
@@ -13743,6 +14024,20 @@ msgstr "Stien fører ikke til Node!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ugyldigt indeks egenskabsnavn '%s' i noden %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funktioner:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ændre størrelsen på Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Ugyldigt argument af typen: "
@@ -13752,6 +14047,10 @@ msgid ": Invalid arguments: "
msgstr ": Ugyldige argumenter: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet blev ikke fundet i scriptet: "
@@ -13760,6 +14059,63 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet blev ikke fundet i scriptet: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Tilføj Preload Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Tidssøgning Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Gem Scene"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Selv"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Indsæt Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Brugerdefinerede node har ingen _step() metode, kan ikke behandle graf."
@@ -13772,15 +14128,75 @@ msgstr ""
"Ugyldig retur værdi fra _step(), skal være heltal (seq ud), eller en streng "
"(fejl)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Kald"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanter"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Tilføj Funktion"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Fjern VisualScript Node"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Flyt Node(s)"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fysik Frame %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaler"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaler"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instans"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14399,7 +14815,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14633,7 +15058,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/de.po b/editor/translations/de.po
index 27b04cd77b..33f5042f4d 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -23,7 +23,7 @@
# Peter Friedland <peter_friedland@gmx.de>, 2016.
# No need for a name <endoplasmatik@gmx.net>, 2016.
# Sönke <me@eknoes.de>, 2018.
-# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021.
+# So Wieso <sowieso@dukun.de>, 2016-2018, 2019, 2020, 2021, 2022.
# Tim Schellenberg <smwleod@gmail.com>, 2017.
# Timo Schwarzer <account@timoschwarzer.com>, 2016-2018.
# viernullvier <hannes.breul+github@gmail.com>, 2016.
@@ -80,8 +80,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-01-03 03:55+0000\n"
-"Last-Translator: Antonio Noack <corperateraider@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: So Wieso <sowieso@dukun.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -392,9 +392,8 @@ msgid "Duplicate Key(s)"
msgstr "Schlüsselbilder duplizieren"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "%d Frame(s) hinzufügen"
+msgstr "RESET Wert(e) hinzufügen"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -431,6 +430,7 @@ msgstr "%d NEUE Spuren erstellen und Schlüsselbilder hinzufügen?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -567,9 +567,8 @@ msgstr ""
"sich nur um eine einzige Spur handelt."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "Schlüsselbilder skalieren"
+msgstr "Anim RESET Werte hinzufügen"
#: editor/animation_track_editor.cpp
msgid ""
@@ -902,6 +901,7 @@ msgstr "Hinzufügen"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -953,8 +953,7 @@ msgstr "Signal kann nicht verbunden werden"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1562,7 +1561,7 @@ msgstr "Ungültiger Name."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Darf nicht mit Ziffer beginnen."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -2031,7 +2030,6 @@ msgid "New Folder..."
msgstr "Neuer Ordner..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Aktualisieren"
@@ -2148,7 +2146,8 @@ msgstr "Verzeichnisse & Dateien:"
msgid "Preview:"
msgstr "Vorschau:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Datei:"
@@ -2198,9 +2197,8 @@ msgid "Properties"
msgstr "Eigenschaften"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "Überschreibungen:"
+msgstr "Überschreibt %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2323,7 +2321,7 @@ msgstr "Methode"
msgid "Signal"
msgstr "Ereignis"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstante"
@@ -2340,20 +2338,23 @@ msgid "Property:"
msgstr "Eigenschaft:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(Wert)"
+msgstr "Wert anheften"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"Einen Wert anzuheften bedeutet dass er selbst dann gespeichert wird, wenn er "
+"sich nicht vom Standardwert unterscheidet."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
-msgstr ""
+msgstr "Wert anheften [deaktiviert da ‚%s‘ Editor-exclusiv ist]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "%s setzen"
@@ -2364,26 +2365,23 @@ msgstr "Mehrfach festlegen:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "%s angeheftet"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "%s losgelöst"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Eigenschaften kopieren"
+msgstr "Eigenschaft kopieren"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Eigenschaften einfügen"
+msgstr "Eigenschaft einfügen"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Skriptpfad kopieren"
+msgstr "Eigenschaft-Pfad kopieren"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3123,8 +3121,9 @@ msgid "Install Android Build Template..."
msgstr "Android-Build-Vorlage installieren..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Projektdatenordner öffnen"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Editordateiverzeichnis öffnen"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3213,7 +3212,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "Shader-Fallbacks forcieren"
#: editor/editor_node.cpp
msgid ""
@@ -3224,6 +3223,13 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"Falls diese Option gesetzt ist, werden Shader die gesamte Laufzeit in ihrer "
+"Fallback-Form genutzt (entweder sichtbar mittels Übershader oder "
+"verborgen).\n"
+"Dies ist hilfreich um Aussehen und Performance der Fallbacks zu überprüfen, "
+"welche üblicherweise nur kurzfristig angezeigt werden.\n"
+"Asynchrone Shader-Kompilierung muss in den Projekteinstellungen aktiviert "
+"sein, sonst hat diese Option keine Auswirkung."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3283,10 +3289,6 @@ msgid "Toggle Fullscreen"
msgstr "Vollbildmodus umschalten"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Systemkonsole umschalten"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Editordaten-/Einstellungenordner öffnen"
@@ -3517,6 +3519,7 @@ msgid "Load Errors"
msgstr "Ladefehler"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Auswählen"
@@ -3593,7 +3596,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3838,6 +3840,12 @@ msgstr "Szenenpfad:"
msgid "Import From Node:"
msgstr "Aus Node importieren:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Fehler"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Den Ordner der diese Exportvorlagen enthält öffnen."
@@ -4380,9 +4388,8 @@ msgid "Replace..."
msgstr "Ersetzen..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Alle ersetzen"
+msgstr "In Dateien ersetzen"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4393,9 +4400,8 @@ msgid "Replace: "
msgstr "Ersetzen: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Alle ersetzen"
+msgstr "Alle ersetzen (KEIN RÜCKGÄNGIG MACHEN)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4625,6 +4631,8 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Zum Anpassen der Importeinstellungen muss eine Ressourcendatei im "
+"Dateisystem oder im Inspektor ausgewählt werden."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4734,6 +4742,7 @@ msgid "Subfolder:"
msgstr "Unterverzeichnis:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6091,9 +6100,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt+Ziehen = Ausgewähltes Node verschieben."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+Ziehen = Ausgewähltes Node verschieben."
+msgstr "Alt+Ziehen = Ausgewähltes Node skalieren."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6127,7 +6135,7 @@ msgstr "Skalierungsmodus"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Umschalt: Proportionales Skalieren."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6228,9 +6236,8 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Sperren ausgewählt"
+msgstr "Gewählte Nodes sperren"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6239,9 +6246,8 @@ msgstr "Das ausgewählte Objekt entsperren (kann bewegt werden)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Auswahl entsperren"
+msgstr "Gewählte Nodes entsperren"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6250,9 +6256,8 @@ msgstr "Verhindert das Auswählen von Unterobjekten dieses Nodes."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Auswahl gruppieren"
+msgstr "Gewählte Nodes gruppieren"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6261,9 +6266,8 @@ msgstr "Stellt die Auswählbarkeit aller Unterobjekte wieder her."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Auswahl entgruppieren"
+msgstr "Gruppierung gewählter Nodes auflösen"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6436,6 +6440,7 @@ msgid "Zoom to 1600%"
msgstr "Auf 1600% vergrößern"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "%s hinzufügen"
@@ -7914,9 +7919,8 @@ msgid "Find in Files..."
msgstr "In Dateien suchen..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Ersetzen..."
+msgstr "In Dateien ersetzen..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -8449,16 +8453,15 @@ msgstr "Freie Kamera umschalten"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "Sichtfeld verkleinern"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "Sichtfeld vergrößern"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "Auf Standardwerte zurücksetzen"
+msgstr "Sichtfeld auf Standardwert zurücksetzen"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9190,22 +9193,19 @@ msgstr "Typ hinzufügen"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "Liste der Typen filtern oder neuen Typ anlegen:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "Verfügbare Profile:"
+msgstr "Verfügbare Node-basierte Typen:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "Dateiname ist leer."
+msgstr "Name des Typs ist leer!"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Sollen wirklich mehrere Projekte geöffnet werden?"
+msgstr "Soll wirklich ein leerer Typ erstellt werden?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9830,7 +9830,8 @@ msgid "TileSet"
msgstr "Kachelsatz"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Keine Versionsverwaltungserweiterungen verfügbar."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9838,16 +9839,56 @@ msgid "Error"
msgstr "Fehler"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Es wurden keine Dateien zum protokollieren vorgemerkt"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Kein Name angegeben."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Speicherpunkt"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Versionsverwaltungserweiterung ist nicht initialisiert"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Shader-Änderungen:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Shader-Änderungen:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Speicherpunkt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Unterbaum"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Soll wirklich ein leerer Typ erstellt werden?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Zurücksetzen durchführen"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9858,16 +9899,148 @@ msgid "Initialize"
msgstr "Initialisieren"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Speicherauswahlbereich"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Punkt entfernen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Umbenennen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Neue Veränderungen beachten"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Veränderungen"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Schließen und Änderungen speichern?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Speichere lokale Änderungen..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materialänderungen:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Änderungen als Speicherpunkt sichern"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Änderungen als Speicherpunkt sichern"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Speicherpunkt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Treffer:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Erstelle neues Projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Spur entfernen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Fern"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Erstelle neues Projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Entferne Element"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Fern "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Fern "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Quell-Mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9886,30 +10059,23 @@ msgid "Typechange"
msgstr "Dateitypänderung"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Ausgewähltes zum speichern vormerken"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Alles zum speichern vormerken"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Änderungen als Speicherpunkt sichern"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Dateiänderungen anzeigen bevor sie nach der aktuellsten Version gespeichert "
-"werden"
+#, fuzzy
+msgid "View:"
+msgstr "Ansicht"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Kein Dateiunterschied ist aktiv"
+#, fuzzy
+msgid "Split"
+msgstr "Pfad aufteilen"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Änderungen in Dateiänderung verfolgen"
+#, fuzzy
+msgid "Unified"
+msgstr "Bearbeitet"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12068,6 +12234,11 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ein Zweig, der unter einer bereits instantiierten Szene eingehängt ist, kann "
+"nicht gespeichert werden.\n"
+"Um den Zweig als eigene Szene zu speichern, muss er in der originalen Szene "
+"ausgewählt und mittels Rechtsklick auf ihn und folgendem Klick auf „Zweig "
+"als Szene speichern“ gespeichert werden."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -12075,6 +12246,11 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ein Zweig, der Teil einer instantiierten Szene ist, kann nicht gespeichert "
+"werden.\n"
+"Um den Zweig als eigene Szene zu speichern, muss er in der originalen Szene "
+"ausgewählt und mittels Rechtsklick auf ihn und folgendem Klick auf „Zweig "
+"als Szene speichern“ gespeichert werden."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -12615,6 +12791,7 @@ msgid "Export list to a CSV file"
msgstr "Liste als CSV-Datei exportieren"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Ressourcenpfad"
@@ -13465,6 +13642,40 @@ msgstr "Graph aktualisieren"
msgid "Edit Member"
msgstr "Mitglied bearbeiten"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Ausdruck eintragen"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animation"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Eingabetyp nicht wiederholbar: "
@@ -13477,6 +13688,88 @@ msgstr "Iterator wurde ungültig"
msgid "Iterator became invalid: "
msgstr "Iterator wurde ungültig: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Benenne Ordner um:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Neigung:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Typen:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Selbst"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Bei Zeichen %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "%s hinzufügen"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "%s setzen"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "%s angeheftet"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "%s abrufen"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ungültiger Name der Index-Eigenschaft."
@@ -13493,6 +13786,21 @@ msgstr "Pfad führt nicht zu einem Node!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ungültiger Indexeigenschaftsname ‚%s‘ in Node %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "%s setzen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funktionen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Größe des Arrays ändern"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Ungültiger Parameter vom Typ: "
@@ -13502,6 +13810,10 @@ msgid ": Invalid arguments: "
msgstr ": Ungültige Parameter: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet nicht im Skript gefunden: "
@@ -13510,6 +13822,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet nicht im Skript gefunden: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Neu laden"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z-Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z-Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "GDNative Singleton wurde aktiviert"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Zeitsuch-Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Szenenbaum-Bearbeitung"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Selbst"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Nodes trennen"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Eigens erstelltes Node hat keine _step()-Methode, Graph kann nicht "
@@ -13523,13 +13895,75 @@ msgstr ""
"Ungültiger Rückgabewert von _step(), muss Integer (für Sequenzausgabe) oder "
"String (für Fehler) sein."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Aufrufe"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanten"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Lokalkoordinaten verwenden"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Lokalkoordinaten verwenden"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Aktion"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "VisualScript suchen"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "%s abrufen"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Frame verschieben"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Physik-relative Renderzeit %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Ereignis"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Ereignis"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instanz"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14150,13 +14584,15 @@ msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
-msgstr ""
+msgstr "NavigationAgent2D kann nur unter einem Node2D-Node genutzt werden."
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
"The NavigationObstacle2D only serves to provide collision avoidance to a "
"Node2D object."
msgstr ""
+"Der einzige Zweck eines NavigationObstacle2D ist es, Kollisionsvermeidung "
+"für ein Node2D-Objekt bereitzustellen."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -14184,15 +14620,25 @@ msgstr ""
"ParallaxBackground-Node verwenden."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU-basierte Partikel werden vom GLES2-Grafiktreiber nicht unterstützt.\n"
"Stattdessen bitte CPUParticles2D-Nodes verwenden. Die „In CPU-Partikel "
"konvertieren“-Funktion kann dazu verwendet werden."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14428,7 +14874,7 @@ msgstr ""
#: scene/3d/navigation_agent.cpp
msgid "The NavigationAgent can be used only under a spatial node."
-msgstr ""
+msgstr "NavigationAgent kann nur unter einem Spatial-Node genutzt werden."
#: scene/3d/navigation_mesh_instance.cpp
msgid ""
@@ -14443,6 +14889,8 @@ msgid ""
"The NavigationObstacle only serves to provide collision avoidance to a "
"spatial object."
msgstr ""
+"Der einzige Zweck eines NavigationObstacle ist es, Kollisionsvermeidung für "
+"ein Spatial-Objekt bereitzustellen."
#: scene/3d/occluder.cpp
msgid "No shape is set."
@@ -14453,10 +14901,11 @@ msgid "Only uniform scales are supported."
msgstr "Es werden nur gleichförmige Skalierungen unterstützt."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPU-basierte Partikel werden vom GLES2-Grafiktreiber nicht unterstützt.\n"
"Stattdessen bitte CPUParticles-Nodes verwenden. Die „In CPU-Partikel "
@@ -14464,6 +14913,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Nichts ist sichtbar da keine Meshe den Zeichendurchläufen zugewiesen wurden."
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index ab1796503c..e41400290d 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -352,6 +352,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -801,6 +802,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -850,8 +852,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1874,7 +1875,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1991,7 +1991,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2159,7 +2160,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2189,6 +2190,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2882,7 +2885,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3017,10 +3020,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3237,6 +3236,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3313,7 +3313,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3538,6 +3537,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4393,6 +4397,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6036,6 +6041,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9318,7 +9324,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9326,7 +9332,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9334,7 +9345,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9346,39 +9385,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9386,15 +9441,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11903,6 +12050,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12731,6 +12879,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12743,6 +12923,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12759,6 +13013,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12768,6 +13034,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12776,6 +13046,54 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12785,12 +13103,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13352,7 +13722,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13565,7 +13944,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 1235fd00fe..b24b443b09 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -371,6 +371,7 @@ msgstr "ΔημιουÏγία %d νέων κομματιών και εισαγωÎ
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -847,6 +848,7 @@ msgstr "ΠÏοσθήκη"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -898,8 +900,7 @@ msgstr "ΑδÏνατη η σÏνδεση σήματος"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1980,7 +1981,6 @@ msgid "New Folder..."
msgstr "Îέος φάκελος..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Ανανέωση"
@@ -2097,7 +2097,8 @@ msgstr "Φάκελοι & ΑÏχεία:"
msgid "Preview:"
msgstr "ΠÏοεπισκόπηση:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "ΑÏχείο:"
@@ -2276,7 +2277,7 @@ msgstr "Μέθοδος"
msgid "Signal"
msgstr "Σήμα"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "ΣταθεÏή"
@@ -2307,6 +2308,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Θέσε %s"
@@ -3073,8 +3076,9 @@ msgid "Install Android Build Template..."
msgstr "Εγκατάσταση ΠÏοτÏπου Δόμησης Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Άνοιγμα φακέλου δεδομένων έÏγου"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Άνοιγμα φακέλου δεδομένων επεξεÏγαστή"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3236,10 +3240,6 @@ msgid "Toggle Fullscreen"
msgstr "Εναλλαγή πλήÏους οθόνης"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Εναλλαγή Κονσόλας Συστήματος"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Άνοιγμα φακέλου δεδομένων/Ïυθμίσεων επεξεÏγαστή"
@@ -3479,6 +3479,7 @@ msgid "Load Errors"
msgstr "Σφάλματα φόÏτωσης"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Επιλογή"
@@ -3559,7 +3560,6 @@ msgid "Author"
msgstr "ΣυγγÏαφείς"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Κατάσταση"
@@ -3800,6 +3800,12 @@ msgstr "ΔιαδÏομή σκηνής:"
msgid "Import From Node:"
msgstr "Εισαγωγή σκηνής από κόμβο:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Σφάλμα"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4719,6 +4725,7 @@ msgid "Subfolder:"
msgstr "Υποφάκελος:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "ΣυγγÏαφέας:"
@@ -6441,6 +6448,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "ΠÏόσθεσε %s"
@@ -9939,7 +9947,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Κανένα Ï€Ïόσθετο VCS δεν είναι διαθέσιμο."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9947,16 +9956,56 @@ msgid "Error"
msgstr "Σφάλμα"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Κανένα αÏχείο δεν Ï€Ïοστέθηκε στο στάδιο"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Δεν δόθηκε όνομα."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Υποβολή"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Το ΠÏόσθετο VCS δεν αÏχικοποιήθηκε"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Αλλαγές Ï€ÏογÏάμματος σκίασης"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Αλλαγές Ï€ÏογÏάμματος σκίασης"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Υποβολή"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "ΥπόδεντÏο"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Είστε σίγουÏοι πως θέλετε να ανοίξετε πεÏισσότεÏα από ένα έÏγα;"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "ΕπαναφοÏά"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9967,16 +10016,148 @@ msgid "Initialize"
msgstr "ΑÏχικοποιήστε"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Σταθμός ανάπαυσης"
+#, fuzzy
+msgid "Remote Login"
+msgstr "ΑφαίÏεση Σημείου"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Μετονομασία"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Εντόπισε νέες αλλαγές"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Αλλαγές"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Κλείσιμο και αποθήκευση αλλαγών;"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Αποθήκευση τοπικών αλλαγών..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Αλλαγές υλικοÏ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Αλλαγές Δέσμευσης"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Αλλαγές Δέσμευσης"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Υποβολή"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Αντιστοιχίες:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "ΔημιουÏγία νέου έÏγου"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "ΑφαίÏεση ÎšÎ¿Î¼Î¼Î±Ï„Î¹Î¿Ï ÎšÎ¯Î½Î·ÏƒÎ·Ï‚"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "ΑπομακÏυσμένο"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "ΔημιουÏγία νέου έÏγου"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "ΑφαίÏεση στοιχείου"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "ΑπομακÏυσμένο "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "ΑπομακÏυσμένο "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Πηγαίο πλέγμα:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9995,28 +10176,23 @@ msgid "Typechange"
msgstr "ΑλλαγήτÏπου"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Στάδιο Επιλέχθηκε"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Διεξαγωγή Όλων"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Αλλαγές Δέσμευσης"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Δείτε τις διαφοÏές αÏχείων Ï€Ïιν τις δεσμεÏσετε στην τελική έκδοση"
+#, fuzzy
+msgid "View:"
+msgstr "Θέα"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Καμία διαφοÏά αÏχείων δεν είναι ενεÏγή"
+#, fuzzy
+msgid "Split"
+msgstr "ΔιαχωÏισμός διαδÏομής"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Ελέγξτε αλλαγές στις διαφοÏές αÏχείων"
+#, fuzzy
+msgid "Unified"
+msgstr "ΤÏοποποιήθηκε"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12726,6 +12902,7 @@ msgid "Export list to a CSV file"
msgstr "Εξαγωγή λίστας σε αÏχείο CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "ΔιαδÏομή πόÏου"
@@ -13593,6 +13770,40 @@ msgstr "Ανανέωση ΓÏαφήματος"
msgid "Edit Member"
msgstr "ΕπεξεÏγασία Μέλους"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "ΟÏισμός έκφÏασης"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Κίνηση"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Δεν μποÏεί να γίνει επανάληψη στον εισηγμένο Ï„Ïπο: "
@@ -13605,6 +13816,88 @@ msgstr "Ο επαναλήπτης έγινε άκυÏος"
msgid "Iterator became invalid: "
msgstr "Ο επαναλήπτης έγινε άκυÏος: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Μετονομασία καταλόγου:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Τόνος"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "ΤÏπος:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Εαυτός"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Στον χαÏακτήÏα %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "ΠÏόσθεσε %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Θέσε %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "ΠÏόσθεσε %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Διάβασε %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "ΆκυÏο όνομα ιδιότητας δείκτη."
@@ -13621,6 +13914,21 @@ msgstr "Η διαδÏομή δεν οδηγεί σε κόμβο!"
msgid "Invalid index property name '%s' in node %s."
msgstr "ΆκυÏο όνομα ιδιότητας δείκτη '%s' στον κόμβο %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Θέσε %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "ΣυναÏτήσεις"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Αλλαγή μεγέθους πίνακα"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": ΆκυÏη παÏάμετÏος Ï„Ïπου: "
@@ -13630,6 +13938,10 @@ msgid ": Invalid arguments: "
msgstr ": ΆκυÏοι παÏάμετÏοι: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Το VariableGet δεν βÏέθηκε στη δέσμη ενεÏγειών: "
@@ -13638,6 +13950,66 @@ msgid "VariableSet not found in script: "
msgstr "Το VariableSet δεν βÏέθηκε στη δέσμη ενεÏγειών: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "ΕπαναφόÏτωση"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Δείκτης Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Δείκτης Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "ΣταθεÏή"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "ΣταθεÏή"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "ΣταθεÏή"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "ΣταθεÏή"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "ΕνεÏγοποίηση Μονοσυνόλου GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Κόμβος εÏÏεσης χÏόνου"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "ΕπεξεÏγασία ΔέντÏου Σκηνής"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Εαυτός"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Αποκοπή κόμβων"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Ο κόμβος δεν έχει τη μέθοδο _step(), αδÏνατη η επεξεÏγασία του γÏαφήματος."
@@ -13650,13 +14022,75 @@ msgstr ""
"ΆκυÏος Ï„Ïπος επιστÏοφής από την _step(), Ï€Ïέπει να είναι ακέÏαιος (seq out) "
"ή ακολουθία χαÏακτήÏων (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Κλήσεις"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ΣταθεÏές"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "ΧÏησιμοποιείστε Τοπικό ΧώÏο"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "ΧÏησιμοποιείστε Τοπικό ΧώÏο"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ΕνέÏγεια"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Αναζήτηση VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Διάβασε %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Μετακίνηση ΚαÏέ"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "KαÏέ φυσικής %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Σήμα"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Σήμα"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Στιγμιότυπο"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14310,15 +14744,25 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Τα σωματίδια GPU δεν υποστηÏίζονται από τον οδηγό βίντεο GLES2.\n"
"ΧÏησιμοποιήστε τον κόμβο CPUParticles2D. ΜποÏείτε να χÏησιμοποιήσετε την "
"επιλογή «Convert to CPUParticles» για αυτόν τον σκοπό."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14578,10 +15022,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Τα σωματίδια GPU δεν υποστηÏίζονται από τον οδηγό βίντεο GLES2.\n"
"ΧÏησιμοποιήστε τον κόμβο CPUParticles. ΜποÏείτε να χÏησιμοποιήσετε την "
@@ -14589,6 +15034,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Τίποτα δεν είναι οÏατό, επειδή δεν έχουν οÏιστεί πεÏάσματα για τα πλέγματα."
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index f3aa813e83..0049194bfe 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -366,6 +366,7 @@ msgstr "Krei %d NOVAJN trakojn kaj enmeti Ålosilojn?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -833,6 +834,7 @@ msgstr "Aldoni"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -884,8 +886,7 @@ msgstr "Ne povas konekti signalo"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1949,7 +1950,6 @@ msgid "New Folder..."
msgstr "Nova dosierujo..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Aktualigi"
@@ -2066,7 +2066,8 @@ msgstr "Dosierujoj kaj dosieroj:"
msgid "Preview:"
msgstr "AntaÅ­rigardo:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Dosiero:"
@@ -2242,7 +2243,7 @@ msgstr "Metodo"
msgid "Signal"
msgstr "Signalo"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstanto"
@@ -2273,6 +2274,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Agordis %s"
@@ -3028,8 +3031,9 @@ msgid "Install Android Build Template..."
msgstr "Instali Androidan muntadan Åablonon..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Malfermi projektan datuman dosierujon"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Malfermi datumajn dosierujon de la redaktilo"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3187,10 +3191,6 @@ msgid "Toggle Fullscreen"
msgstr "Baskuli plenekranon"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Baskuli la konzolon de sistemo"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Malfermi datumajn/agordajn dosierujon de la redaktilo"
@@ -3416,6 +3416,7 @@ msgid "Load Errors"
msgstr "Åœargaj eraroj"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Elekti"
@@ -3497,7 +3498,6 @@ msgid "Author"
msgstr "AÅ­toroj"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3740,6 +3740,12 @@ msgstr "Scena dosierindiko:"
msgid "Import From Node:"
msgstr "Enporti el nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Eraro!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4654,6 +4660,7 @@ msgid "Subfolder:"
msgstr "Subdosierujo:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "AÅ­toro:"
@@ -6358,6 +6365,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Aldoni %s"
@@ -9759,7 +9767,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9767,18 +9775,57 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Ne nomon provizis."
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "ÅœanÄu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "ÅœanÄu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komunumo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Ĉu vi certe volas malfermi plurajn projektojn?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Almeti rekomencigon"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9787,7 +9834,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Forigi punkton"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renomi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9796,54 +9873,147 @@ msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
+msgid "Discard all changes"
+msgstr "Parametro ÅanÄiÄis"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Memoras lokajn ÅanÄojn..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Parametro ÅanÄiÄis"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
msgstr "ÅœanÄu"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr "Modifita"
+#, fuzzy
+msgid "Commit Changes"
+msgstr "ÅœanÄu"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+#, fuzzy
+msgid "Commit List"
+msgstr "ÅœanÄu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Forigi Åœlosilo(j)n"
+msgid "Branches"
+msgstr "Matĉoj:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "ÅœanÄu"
+msgid "Create New Branch"
+msgstr "Krei novan projekton"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Skali Elektaron"
+msgid "Remove Branch"
+msgstr "Forigi animacian trakon"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Elektaro ĉiuj"
+msgid "Remotes"
+msgstr "Fora"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "ÅœanÄu"
+msgid "Create New Remote"
+msgstr "Krei novan projekton"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Forigi elementon"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Fora "
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Remote URL"
+msgstr "Fora "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
msgstr ""
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Risurca Vojo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr "Modifita"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Forigi Åœlosilo(j)n"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "ÅœanÄu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Vido"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unified"
+msgstr "Modifita"
+
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
msgstr ""
@@ -12423,6 +12593,7 @@ msgid "Export list to a CSV file"
msgstr "Eksporti liston al CSV dosiero"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Risurca Vojo"
@@ -13270,6 +13441,40 @@ msgstr "Aktualigi"
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Uzi regulesprimojn"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animacio"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13282,6 +13487,86 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renomas dosierujon:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipo"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Memo"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Aldoni %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Agordis %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Aldoni %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13298,6 +13583,21 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Agordis %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcioj:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Regrandigi Vicon"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13307,6 +13607,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13315,6 +13619,65 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "ReÅargi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Indekso:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Defini stirilon"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstanto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstanto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstanto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstanto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nova radiko de sceno"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Redaktado de scenoarbo"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Memo"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Eltondi nodo(j)n"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13324,14 +13687,76 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Alvokoj"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstantoj"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Uzi lokan spacon"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Uzi lokan spacon"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Faro"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Posta tabo"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fiziko-kadro %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signalo"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signalo"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Ekzemplodoni"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13911,7 +14336,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14124,7 +14558,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 156a3a5ec5..058549cbd4 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -72,13 +72,14 @@
# davidrogel <david.rogel.pernas@icloud.com>, 2021.
# Anderson Guzman Abreu <chicobello1111@gmail.com>, 2021.
# Manuel Cantón Guillén <manuelcanton8@gmail.com>, 2021.
+# Alfonso V <alfonsov96@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-21 10:39+0000\n"
-"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Alfonso V <alfonsov96@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -86,7 +87,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.10\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -430,6 +431,7 @@ msgstr "¿Crear %d nuevas pistas e insertar claves?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -901,6 +903,7 @@ msgstr "Añadir"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -952,8 +955,7 @@ msgstr "No se puede conectar la señal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2027,7 +2029,6 @@ msgid "New Folder..."
msgstr "Nueva Carpeta..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Recargar"
@@ -2144,7 +2145,8 @@ msgstr "Directorios y Archivos:"
msgid "Preview:"
msgstr "Vista Previa:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Archivo:"
@@ -2175,7 +2177,7 @@ msgstr "Clase:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
#: editor/script_create_dialog.cpp
msgid "Inherits:"
-msgstr "Hereda:"
+msgstr "Hereda de:"
#: editor/editor_help.cpp
msgid "Inherited by:"
@@ -2319,7 +2321,7 @@ msgstr "Método"
msgid "Signal"
msgstr "Señal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2350,6 +2352,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Establecer %s"
@@ -2947,8 +2951,9 @@ msgstr "Eliminar Layout"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
+#, fuzzy
msgid "Default"
-msgstr "Predeterminado"
+msgstr "Por defecto"
#: editor/editor_node.cpp editor/editor_resource_picker.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
@@ -3115,8 +3120,9 @@ msgid "Install Android Build Template..."
msgstr "Instalar plantilla de compilación de Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Abrir Carpeta de Datos del Proyecto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Abrir Carpeta de Editor de Datos"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3276,10 +3282,6 @@ msgid "Toggle Fullscreen"
msgstr "Cambiar a Pantalla Completa"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Act./Desact. Consola del Sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Abrir Editor de Datos/Carpeta de Configuración"
@@ -3512,6 +3514,7 @@ msgid "Load Errors"
msgstr "Errores de carga"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Seleccionar"
@@ -3588,7 +3591,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Estado"
@@ -3834,6 +3836,12 @@ msgstr "Ruta de la Escena:"
msgid "Import From Node:"
msgstr "Importar Desde Nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Error"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Abra la carpeta que contiene estas plantillas."
@@ -4730,6 +4738,7 @@ msgid "Subfolder:"
msgstr "Subcarpeta:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6436,6 +6445,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom al 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Añadir %s"
@@ -9824,7 +9834,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "No hay addons de VCS disponibles."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9832,16 +9843,56 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "No se agregaron archivos al stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nombre no proporcionado."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Confirmar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "El Addon de VCS no está inicializado"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Cambios de sombreado:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Cambios de sombreado:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Confirmar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subárbol"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "¿Seguro que quieres abrir más de un proyecto?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Aplicar Restablecer"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9852,16 +9903,148 @@ msgid "Initialize"
msgstr "Inicializar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Ãrea de Staging"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Eliminar Punto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renombrar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detectar nuevos cambios"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Cambios"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "¿Cerrar y guardar cambios?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Guardando cambios locales..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Cambios del Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Confirmar Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Confirmar Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Confirmar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Coincidencias:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Crear Nuevo Proyecto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Eliminar Pista de Animación"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Crear Nuevo Proyecto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Eliminar Elemento"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Malla de Origen:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9880,29 +10063,23 @@ msgid "Typechange"
msgstr "Cambio de Tipo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Hacer Staging de Selección"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Hacer Staging de Todo"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Confirmar Cambios"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Ver las diferencias de los archivos antes de confirmar la última versión"
+#, fuzzy
+msgid "View:"
+msgstr "Ver"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "No hay diferencias de archivo disponibles"
+#, fuzzy
+msgid "Split"
+msgstr "Dividir Ruta"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detectar diferencias entre los archivos"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificado/s"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12607,6 +12784,7 @@ msgid "Export list to a CSV file"
msgstr "Exportar lista a un archivo CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Ruta de Recursos"
@@ -13458,6 +13636,40 @@ msgstr "Refrescar Gráfico"
msgid "Edit Member"
msgstr "Editar Miembro"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Establecer expresión"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animación"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "El tipo de entrada no es iterable: "
@@ -13470,6 +13682,88 @@ msgstr "El iterador ya no es correcto"
msgid "Iterator became invalid: "
msgstr "El iterador ya no es correcto: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renombrar carpeta:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Eje de paso:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipos:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "En el carácter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Añadir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Establecer %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Añadir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Obtener %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ãndice del nombre de la propiedad inválido."
@@ -13486,6 +13780,21 @@ msgstr "¡La ruta no apunta a un Nodo!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ãndice inválido de nombre de propiedad '%s' en el nodo %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Establecer %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funciones"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionar Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argumento incorrecto de tipo: "
@@ -13495,6 +13804,10 @@ msgid ": Invalid arguments: "
msgstr ": Argumentos incorrectos: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet no encontrado en el script: "
@@ -13503,6 +13816,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet no encontrado en el script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Recargar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Activar Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nodo TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Editor del Ãrbol de Escenas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Cortar Nodos"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"El nodo personalizado no tiene ningún método _step(), no se puede procesar "
@@ -13516,13 +13889,75 @@ msgstr ""
"El valor devuelto por _step() no es correcto, debe ser un entero (seq out), "
"o string/cadena (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Llamadas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usar Espacio Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usar Espacio Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Acción"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Buscar en VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Obtener %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mover Fotograma"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fotogramas de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Señal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Señal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instanciar"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14190,16 +14625,26 @@ msgstr ""
"nodo ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Las partículas basadas en la GPU no son compatibles con el controlador de "
"vídeo GLES2.\n"
"En su lugar, utiliza el nodo CPUParticles2D. Para ello puedes utilizar la "
"opción \"Convertir a CPUParticles\"."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14452,10 +14897,11 @@ msgid "Only uniform scales are supported."
msgstr "Sólo se admiten escalas uniformes."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Las partículas basadas en la GPU no son compatibles con el controlador de "
"vídeo GLES2.\n"
@@ -14464,6 +14910,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"No hay nada visible porque no se han asignado mallas para los pases de "
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 23020a7573..b7dd76951e 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -376,6 +376,7 @@ msgstr "Crear %d NUEVOS tracks e insertar claves?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -845,6 +846,7 @@ msgstr "Agregar"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -896,8 +898,7 @@ msgstr "No se puede conectar la señal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1969,7 +1970,6 @@ msgid "New Folder..."
msgstr "Nueva Carpeta..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Refrescar"
@@ -2086,7 +2086,8 @@ msgstr "Directorios y Archivos:"
msgid "Preview:"
msgstr "Vista Previa:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Archivo:"
@@ -2261,7 +2262,7 @@ msgstr "Método"
msgid "Signal"
msgstr "Señal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2292,6 +2293,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Asignar %s"
@@ -3058,8 +3061,9 @@ msgid "Install Android Build Template..."
msgstr "Instalar Plantilla de Compilación de Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Abrir Carpeta de Datos del Proyecto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Abrir Carpeta de Datos del Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3217,10 +3221,6 @@ msgid "Toggle Fullscreen"
msgstr "Act./Desact. Pantalla Completa"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Act/Desact. Consola de Sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Abrir Carpeta de Datos/Configuración del Editor"
@@ -3453,6 +3453,7 @@ msgid "Load Errors"
msgstr "Erroes de carga"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Seleccionar"
@@ -3529,7 +3530,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Estado"
@@ -3774,6 +3774,12 @@ msgstr "Ruta a la Escena:"
msgid "Import From Node:"
msgstr "Importar Desde Nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Error"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Abrir la carpeta que contiene estas plantillas."
@@ -4672,6 +4678,7 @@ msgid "Subfolder:"
msgstr "Subcarpeta:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6376,6 +6383,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom a 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Agregar %s"
@@ -9756,7 +9764,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "No hay addons de VCS disponibles."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9764,16 +9773,56 @@ msgid "Error"
msgstr "Error"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "No se agregaron archivos al stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "No se indicó ningún nombre."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "El Addon de VCS no está inicializado"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Cambios de Shaders:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Cambios de Shaders:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subárbol"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "¿Estás seguro/a que quieres abrir más de un proyecto?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Aplicar Reset"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9784,16 +9833,148 @@ msgid "Initialize"
msgstr "Inicializar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Ãrea de Staging"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Quitar Punto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renombrar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detectar nuevos cambios"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Cambios"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "¿Cerrar y guardar cambios?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Guardando cambios locales..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Cambios de Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commitear Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commitear Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Coincidencias:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Crear Proyecto Nuevo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Quitar pista de animación"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Crear Proyecto Nuevo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Remover Item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Mesh de Origen:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9812,28 +9993,23 @@ msgid "Typechange"
msgstr "Cambio de Tipo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Hacer Staging de Selección"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Hacer Staging de Todo"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commitear Cambios"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Ver diferencias de archivos antes de commitearlos a la última versión"
+#, fuzzy
+msgid "View:"
+msgstr "Vista"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "No hay ningún diff de archivos activo"
+#, fuzzy
+msgid "Split"
+msgstr "Partir Path"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detectar cambios en el diff de archivo"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificado/s"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12542,6 +12718,7 @@ msgid "Export list to a CSV file"
msgstr "Exportar lista a un archivo CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Ruta de Recursos"
@@ -13389,6 +13566,40 @@ msgstr "Refrescar el Gráfico"
msgid "Edit Member"
msgstr "Editar Miembros"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Establecer expresión"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animación"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tipo de input no iterable: "
@@ -13401,6 +13612,88 @@ msgstr "El iterador se volvió inválido"
msgid "Iterator became invalid: "
msgstr "El iterador se volvió inválido: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renombrar carpeta:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Cabeceo:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipos:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "En el carácter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Agregar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Asignar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Agregar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Obtener %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nombre de propiedad indíce inválido."
@@ -13417,6 +13710,21 @@ msgstr "La ruta no apunta a un Nodo!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nombre de propiedad índice '%s' inválido en nodo %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Asignar %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funciones"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionar Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argumento inválido de tipo: "
@@ -13426,6 +13734,10 @@ msgid ": Invalid arguments: "
msgstr ": Argumentos inválidos: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet no encontrado en el script: "
@@ -13434,6 +13746,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet no encontrado en el script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Volver a Cargar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Activar Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nodo TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edición de Ãrbol de Escenas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Cortar Nodos"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"El nodo personalizado no tiene ningún método _step(), no se puede procesar "
@@ -13447,13 +13819,75 @@ msgstr ""
"Valor de retorno inválido de _step(), debe ser un entero (seq out), o string "
"(error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Llamadas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usar Espacio Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usar Espacio Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Acción"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Buscar en VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Obtener %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mover Fotograma"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Frames de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Señal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Señal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instancia"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14115,16 +14549,26 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Las partículas basadas en la GPU no son compatibles con el controlador de "
"vídeo GLES2.\n"
"En su lugar, utiliza el nodo CPUParticles2D. Para ello podés utilizar la "
"opción \"Convertir a CPUParticles\"."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14378,10 +14822,11 @@ msgid "Only uniform scales are supported."
msgstr "Sólo se admiten escalas uniformes."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Las partículas basadas en la GPU no son compatibles con el controlador de "
"vídeo GLES2.\n"
@@ -14390,6 +14835,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "Nada visible ya que no se asigno pasadas de dibujado a los meshes."
diff --git a/editor/translations/et.po b/editor/translations/et.po
index acb2a18bcf..db162ecca8 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -360,6 +360,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -817,6 +818,7 @@ msgstr "Lisa"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -866,8 +868,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1930,7 +1931,6 @@ msgid "New Folder..."
msgstr "Uus kaust..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Värskenda"
@@ -2047,7 +2047,8 @@ msgstr "Kataloogid ja failid:"
msgid "Preview:"
msgstr "Eelvaade:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fail:"
@@ -2218,7 +2219,7 @@ msgstr "Meetod"
msgid "Signal"
msgstr "Signaal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstant"
@@ -2249,6 +2250,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2960,8 +2963,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr ""
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Ava fail"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3097,10 +3101,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3319,6 +3319,7 @@ msgid "Load Errors"
msgstr "Laadimisvead"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Vali"
@@ -3398,7 +3399,6 @@ msgid "Author"
msgstr "Autorid"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Olek"
@@ -3626,6 +3626,12 @@ msgstr "Stseeni tee:"
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Viga:"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4496,6 +4502,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6146,6 +6153,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9494,7 +9502,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9502,7 +9510,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9510,7 +9523,38 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Varjutaja muutused"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Varjutaja muutused"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Kogukond"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9522,57 +9566,179 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Kustuta profiil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Nimeta ümber"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH private key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
-msgstr "Kustutatud"
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Kustuta Valitud Võti (Võtmed)"
+msgid "Discard all changes"
+msgstr "Materjali muutused"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Vali Kõik"
+msgid "Stage all changes"
+msgstr "Salvestan kohalikud muudatused..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materjali muutused"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Commit List"
+msgstr "Kogukond"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "Branches"
+msgstr "Vasted:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Loo stseen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Eemalda animatsiooni rada"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Eemalda"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Lisa/loo uus sõlm."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Eemalda"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Sõlme nimi:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Eemalda"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Ressursi tee"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Kustutatud"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Kuva"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12101,6 +12267,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Ressursi tee"
@@ -12937,6 +13104,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animatsioon"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12949,6 +13149,82 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Frontaal"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tüüp:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12965,6 +13241,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funktsioonid"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12974,6 +13263,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12982,6 +13275,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Kustuta sõlm(ed)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Stseenipuu redigeerimine"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Kustuta sõlm(ed)"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12991,12 +13339,72 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Kutsungid"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstandid"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Kasuta kohalikku ruumi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Kasuta kohalikku ruumi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Funktsioonid"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Virnakaadrid"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13568,7 +13976,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13782,7 +14199,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 4006cdc00d..448788dc2e 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -360,6 +360,7 @@ msgstr "%d pista berri sortu eta giltzak sartu?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -817,6 +818,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -866,8 +868,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1913,7 +1914,6 @@ msgid "New Folder..."
msgstr "Karpeta berria..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2030,7 +2030,8 @@ msgstr "Direktorioak eta fitxategiak:"
msgid "Preview:"
msgstr "Aurrebista:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fitxategia:"
@@ -2199,7 +2200,7 @@ msgstr "Metodoa"
msgid "Signal"
msgstr "Seinalea"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstantea"
@@ -2230,6 +2231,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2929,8 +2932,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Ireki proiektuaren datu karpeta"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Ireki editorearen datu karpeta"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3065,10 +3069,6 @@ msgid "Toggle Fullscreen"
msgstr "Txandakatu pantaila osoa"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Txandakatu sistemaren kontsola"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3289,6 +3289,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3368,7 +3369,6 @@ msgid "Author"
msgstr "Egileak"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3594,6 +3594,11 @@ msgstr "Eszenaren bidea:"
msgid "Import From Node:"
msgstr "Inportatu nodotik:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4474,6 +4479,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6124,6 +6130,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9453,7 +9460,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9461,7 +9468,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9469,7 +9481,36 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komunitatea"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9481,39 +9522,56 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Ezabatu profila"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "Select SSH private key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9521,15 +9579,113 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Commit List"
+msgstr "Komunitatea"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Create New Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Ezabatu Animazio Pista"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Kendu elementu guztiak"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Kendu elementu guztiak"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Kendu guztiak"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Aurrebista:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12058,6 +12214,7 @@ msgid "Export list to a CSV file"
msgstr "Esportatu zerrenda CSV fitxategi batera"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12888,6 +13045,40 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Erabili adierazpen erregularrak"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Kargatu animazioa"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12900,6 +13091,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12916,6 +13181,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funtzioak:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12925,6 +13203,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12933,6 +13215,60 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstantea"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstantea"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstantea"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstantea"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Blend4 nodoa"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Txertatu gakoa hemen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12942,12 +13278,69 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanteak"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Funtzioak:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Hurrengo karpeta/fitxategia"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Seinalea"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Seinalea"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13519,7 +13912,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13732,7 +14134,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index cea2728671..dee445a3d1 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -23,13 +23,14 @@
# duniyal ras <duniyalr@gmail.com>, 2021.
# عبدالرئو٠عابدی <abdolraoofabedi@gmail.com>, 2021.
# Alireza Khodabande <alirezakhodabande74@gmail.com>, 2021.
+# Seyed Fazel Alavi <fazel8195@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-09-29 02:21+0000\n"
-"Last-Translator: Alireza Khodabande <alirezakhodabande74@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Seyed Fazel Alavi <fazel8195@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -37,7 +38,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.9-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -62,7 +63,7 @@ msgstr "ورودی نامعتبر i% (تایید نشده) در عبارت"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "نمی توان self را بکار Ú¯Ø±ÙØª چون instance = null هست (تایید نشده)"
+msgstr "از self نمی‌توان Ø§Ø³ØªÙØ§Ø¯Ù‡ کرد زیرا نمونه ØµÙØ± است (رد نشده است)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -342,7 +343,7 @@ msgstr "تکرار کلید(ها)"
#: editor/animation_track_editor.cpp
msgid "Add RESET Value(s)"
-msgstr ""
+msgstr "اضاÙÙ‡ کردن مقدار(های) ریست"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -379,6 +380,7 @@ msgstr "ساختن %d قطعه جدید و درج کلیدها؟"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -391,9 +393,8 @@ msgstr "در انیمیشن درج کن"
#. TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "node '%s'"
-msgstr "در حال اتصال..."
+msgstr "گره '%s'"
#. TRANSLATORS: This describes the target of new animation track, will be inserted into another string.
#: editor/animation_track_editor.cpp
@@ -512,9 +513,8 @@ msgid ""
msgstr "این گزینه برای اصلاح Ø¨ÙØ²ÛŒÙر کار نمی کند, چون تنها یک مسیر واحد است."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "اندازه کلید های متحرک"
+msgstr "اضاÙÙ‡ کردن کلید های ریست انیمیشن"
#: editor/animation_track_editor.cpp
msgid ""
@@ -844,6 +844,7 @@ msgstr "Ø§ÙØ²ÙˆØ¯Ù†"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -895,8 +896,7 @@ msgstr "نمی توان سیگنال را متصل کرد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -947,7 +947,7 @@ msgstr ""
#: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp
msgid "Signals"
-msgstr "سیگنال‌ها"
+msgstr "سیگنال ها"
#: editor/connections_dialog.cpp
msgid "Filter signals"
@@ -983,9 +983,8 @@ msgid "Create New %s"
msgstr "ساختن %s جدید"
#: editor/create_dialog.cpp editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "No results for \"%s\"."
-msgstr "هیچ نتیجه ای برای \"٪ s\" وجود ندارد."
+msgstr "هیچ نتیجه ای برای \"%s\" وجود ندارد."
#: editor/create_dialog.cpp editor/property_selector.cpp
msgid "No description available for %s."
@@ -1089,18 +1088,16 @@ msgid "Owners Of:"
msgstr "مالکانÙ:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove the selected files from the project? (Cannot be undone.)\n"
"Depending on your filesystem configuration, the files will either be moved "
"to the system trash or deleted permanently."
msgstr ""
-"ÙØ§ÛŒÙ„های انتخابی از پروژه حذ٠شوند؟ (قابل واگرد نیست.)\n"
+"ÙØ§ÛŒÙ„های انتخابی از پروژه حذ٠شوند؟ (قابل برگشت نیست.)\n"
"بسته به پیکربندی سیستم ÙØ§ÛŒÙ„ شما ØŒ ÙØ§ÛŒÙ„ ها یا به سطل زباله سیستم منتقل Ù…ÛŒ "
"شوند و یا برای همیشه حذ٠می شوند."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1280,41 +1277,36 @@ msgid "Licenses"
msgstr "گواهینامه"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Error opening asset file for \"%s\" (not in ZIP format)."
-msgstr "خطای گشودن بسته بندی پرونده، به شکل ZIP نیست."
+msgstr "خطا در بازکردن ÙØ§ÛŒÙ„ برای \"%s\" (ÙØ±Ù…ت ZIP نمیباشد)."
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (already exists)"
-msgstr "%s (موجود است)"
+msgstr "\"%s\" (در حال حاضر موجود است)"
#: editor/editor_asset_installer.cpp
msgid "Contents of asset \"%s\" - %d file(s) conflict with your project:"
-msgstr ""
+msgstr "محتوای دارایی \"%s\" - %d ÙØ§ÛŒÙ„(ها) با پروژه شما تضاد دارد:"
#: editor/editor_asset_installer.cpp
msgid "Contents of asset \"%s\" - No files conflict with your project:"
-msgstr ""
+msgstr "محتویات دارایی \"%s\" - هیچ ÙØ§ÛŒÙ„ÛŒ با پروژه شما مغایرت ندارد:"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
msgstr "ÙØ´Ø±Ø¯Ù‡ نشدن Ø§ÙŽØ³ÙØª ها"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "The following files failed extraction from asset \"%s\":"
-msgstr "استخراج پرونده های زیر از بسته بندی انجام نشد:"
+msgstr "ÙØ§ÛŒÙ„‌های زیر از دارایی \"%s\" استخراج نشدند:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "(and %s more files)"
-msgstr "و %s بیش تر پرونده ها."
+msgstr "(Ùˆ %s دیگر ÙØ§ÛŒÙ„ ها)"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Asset \"%s\" installed successfully!"
-msgstr "بسته با موÙقیت نصب شد!"
+msgstr "دارایی \"%s\" با موÙقیت نصب شد!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -1326,9 +1318,8 @@ msgid "Install"
msgstr "نصب کردن"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Asset Installer"
-msgstr "نصب کننده پکیج ها"
+msgstr "نصب کننده دارایی"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
@@ -1391,7 +1382,6 @@ msgid "Bypass"
msgstr "‌گذرگاه ÙØ±Ø¹ÛŒ"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Bus Options"
msgstr "گزینه های اتوبوس"
@@ -1508,7 +1498,7 @@ msgstr "نام نامعتبر."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "نمی توان با یک رقم شروع کرد."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1563,13 +1553,12 @@ msgid "Can't add autoload:"
msgstr "اضاÙÙ‡ کردن خودکار امکان پذیر نیست:"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "%s is an invalid path. File does not exist."
-msgstr "پرونده موجود نیست."
+msgstr "%s یک مسیر نامعتبر است. ÙØ§ÛŒÙ„ موجود نمیباشد."
#: editor/editor_autoload_settings.cpp
msgid "%s is an invalid path. Not in resource path (res://)."
-msgstr ""
+msgstr "%s یک مسیر نامعتبر است. در مسیر منبع نیست (//:res)."
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1593,9 +1582,8 @@ msgid "Name"
msgstr "نام"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Global Variable"
-msgstr "تغییر متغیر"
+msgstr "متغیر عمومی"
#: editor/editor_data.cpp
msgid "Paste Params"
@@ -1671,12 +1659,16 @@ msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"Ù¾Ù„ØªÙØ±Ù… مورد نظر به ÙØ´Ø±Ø¯Ù‡ سازی تکستچر 'ETC' برای GLES2 نیاز دارد . 'واردکردن "
+"ETC' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"Ù¾Ù„ØªÙØ±Ù… مورد نظر به ÙØ´Ø±Ø¯Ù‡ سازی تکستچر 'ETC' برای GLES2 نیاز دارد . 'واردکردن "
+"ETC' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید."
#: editor/editor_export.cpp
msgid ""
@@ -1685,18 +1677,26 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"Ù¾Ù„ØªÙØ±Ù… هد٠به ÙØ´Ø±Ø¯Ù‡â€ŒØ³Ø§Ø²ÛŒ Ø¨Ø§ÙØª 'ETC' برای بازگرداندن درایور به GLES2 نیاز "
+"دارد.\n"
+"'استخراج Etc' را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید یا \"Driver Fallback Enabled\" "
+"را ØºÛŒØ±ÙØ¹Ø§Ù„ کنید."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
"'Import Pvrtc' in Project Settings."
msgstr ""
+"پلت ÙØ±Ù… هد٠به ÙØ´Ø±Ø¯Ù‡ سازی Ø¨Ø§ÙØª 'PVRTC' برای GLES2 نیاز دارد. 'استخراج Pvrtc' "
+"را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
+"پلت ÙØ±Ù… هد٠برای GLES3 به ÙØ´Ø±Ø¯Ù‡ سازی Ø¨Ø§ÙØª 'ETC2' یا 'PVRTC' نیاز دارد. "
+"\"Import Etc 2\" یا \"Import Pvrtc\" را در تنظیمات پروژه ÙØ¹Ø§Ù„ کنید."
#: editor/editor_export.cpp
msgid ""
@@ -1957,7 +1957,6 @@ msgid "New Folder..."
msgstr "ساختن پوشه..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2074,7 +2073,8 @@ msgstr "پوشه‌ها و پرونده‌ها:"
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "پرونده:"
@@ -2131,7 +2131,7 @@ msgstr "پیش ÙØ±Ø¶:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr "توابع"
+msgstr "روش ها"
#: editor/editor_help.cpp
msgid "Theme Properties"
@@ -2242,7 +2242,7 @@ msgstr "روش"
msgid "Signal"
msgstr "سیگنال‌"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "ثابت"
@@ -2273,6 +2273,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "تنظیم %s"
@@ -2972,7 +2974,8 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
msgstr "گشودن پوشه اطلاعات طرح"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3112,11 +3115,6 @@ msgstr "حالت تمام ØµÙØ­Ù‡"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Toggle System Console"
-msgstr "یک Breakpoint درج کن"
-
-#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
msgstr "ویرایشگر ترجیحات"
@@ -3348,6 +3346,7 @@ msgid "Load Errors"
msgstr "خطاهای بارگذاری"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3431,7 +3430,6 @@ msgid "Author"
msgstr "Ù…Ø¤Ù„ÙØ§Ù†"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
#, fuzzy
msgid "Status"
@@ -3665,6 +3663,12 @@ msgstr ""
msgid "Import From Node:"
msgstr "وارد کردن از گره:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "بازتاب"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4600,6 +4604,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "خالق:"
@@ -6360,6 +6365,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -6489,7 +6495,7 @@ msgstr ""
#: editor/plugins/curve_editor_plugin.cpp
msgid "Flat 1"
-msgstr ""
+msgstr "تخت 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
@@ -9917,7 +9923,7 @@ msgid "TileSet"
msgstr "صدور مجموعه کاشی"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9925,7 +9931,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9934,10 +9945,43 @@ msgid "Commit"
msgstr "انجمن"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "تغییر بده"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "تغییر بده"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "انجمن"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "آیا مطمئن هستید که می خواهید همه اتصالات را از این سیگنال حذ٠کنید؟"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "بازنشانی را اعمال کنید"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9946,7 +9990,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "برداشتن نقطه"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "تغییر نام"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9956,53 +10030,145 @@ msgstr "ساختن %s جدید"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
+msgid "Discard all changes"
msgstr "تغییر بده"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr ""
+#, fuzzy
+msgid "Stage all changes"
+msgstr "ذخیره تغییرات محلی ..."
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "تغییر نام"
+msgid "Unstage all changes"
+msgstr "تغییر بده"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "حذ٠کن"
+msgid "Commit Message"
+msgstr "تغییر بده"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
+msgid "Commit Changes"
msgstr "تغییر بده"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "انتخاب شده را حذ٠کن"
+msgid "Commit List"
+msgstr "انجمن"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "انتخاب همه"
+msgid "Branches"
+msgstr "تطبیق‌ها:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "تغییر بده"
+msgid "Create New Branch"
+msgstr "ساختن پروژه جدید"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "حذ٠ترک انیمشین"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Remotes"
+msgstr "از راه دور"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "ساختن پروژه جدید"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "حذ٠قالب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "برداشتن"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "برداشتن"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "تغییر نام"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "حذ٠کن"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "تغییر بده"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "پرونده:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "ویرایش منحنی گره"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12666,6 +12832,7 @@ msgid "Export list to a CSV file"
msgstr "صدور پروژه"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13566,6 +13733,40 @@ msgstr ""
msgid "Edit Member"
msgstr "عضوها"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "انتقال را در انیمیشن تغییر بده"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "انیمیشن"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "نوع ورودی قابل تکرار نیست: "
@@ -13580,6 +13781,85 @@ msgstr "تکرارگر نامعتبر شد"
msgid "Iterator became invalid: "
msgstr "تکرارگر نامعتبر شد: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "ساختن پوشه"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "سوییچ"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "نوع پایه:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "کاراکترهای معتبر:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "تنظیم %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Ú¯Ø±ÙØªÙ† %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "نام دارایی ایندکس نامعتبر."
@@ -13596,6 +13876,21 @@ msgstr "مسیر به یک نود نمیرسد!"
msgid "Invalid index property name '%s' in node %s."
msgstr "نام دارایی ایندکس نامعتبر '%s' در نود %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "تنظیم %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "توابع"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "آرایه را تغییر اندازه بده"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": آرگومان نوع نامعتبر "
@@ -13605,6 +13900,10 @@ msgid ": Invalid arguments: "
msgstr ": آرگومان‌های نامعتبر: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet در اسکریپت پیدا نشد: "
@@ -13613,6 +13912,64 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet در اسکریپت پیدا نشد: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "اندیس:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "اندیس:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "ثابت"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "صحنه جدید"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "ساختن گره"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "ساختن گره"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "گره Ø³ÙØ§Ø±Ø´ÛŒ بدون متد ()step_ نمی‌تواند گرا٠را پردازش کند."
@@ -13625,14 +13982,74 @@ msgstr ""
"مقدار بازگشتی نامعتبر از ()step_ ، باید integer (seq out) ، یا string "
"(error) باشد."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "ÙØ±Ø§Ø®ÙˆØ§Ù†ÛŒ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ثابت ها"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "محلی"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "محلی"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Ø§ÙØ²ÙˆØ¯Ù† وظیÙÙ‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "حذ٠گره اسکریپت٠دیداری"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Ú¯Ø±ÙØªÙ† %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "حرکت دادن گره(ها)"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "سیگنال‌"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "سیگنال‌"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
+msgstr ""
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14248,7 +14665,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14484,7 +14910,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index f461bb0074..ab1acf1db8 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -8,7 +8,7 @@
# Jarmo Riikonen <amatrelan@gmail.com>, 2017.
# Nuutti Varvikko <nvarvikko@gmail.com>, 2018.
# Sami Lehtilä <sami.lehtila@gmail.com>, 2018.
-# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021.
+# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021, 2022.
# Tuomas Lähteenmäki <lahtis@gmail.com>, 2019.
# Matti Niskanen <matti.t.niskanen@gmail.com>, 2020.
# Severi Vidnäs <severi.vidnas@gmail.com>, 2021.
@@ -17,7 +17,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-11 06:25+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -26,7 +26,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.10-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -329,9 +329,8 @@ msgid "Duplicate Key(s)"
msgstr "Kahdenna avainruudut"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "Lisää %d ruutua"
+msgstr "Lisää RESET arvo(t)"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -368,6 +367,7 @@ msgstr "Luo %d uutta raitaa ja lisää avaimet?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -500,9 +500,8 @@ msgid ""
msgstr "Tämä valinta ei käy Bezier-editoinnille, koska se on vain yksi raita."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "Animaatio: Skaalaa avaimia"
+msgstr "Animaatio: Lisää RESET avaimet"
#: editor/animation_track_editor.cpp
msgid ""
@@ -832,6 +831,7 @@ msgstr "Lisää"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -882,8 +882,7 @@ msgstr "Ei voida yhdistää signaalia"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1487,7 +1486,7 @@ msgstr "Virheellinen nimi."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Ei voi alkaa numerolla."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1951,7 +1950,6 @@ msgid "New Folder..."
msgstr "Uusi kansio..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Päivitä"
@@ -2068,7 +2066,8 @@ msgstr "Hakemistot ja tiedostot:"
msgid "Preview:"
msgstr "Esikatselu:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Tiedosto:"
@@ -2117,9 +2116,8 @@ msgid "Properties"
msgstr "Ominaisuudet"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "ylikirjoita:"
+msgstr "ylikirjoittaa %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2242,7 +2240,7 @@ msgstr "Metodi"
msgid "Signal"
msgstr "Signaali"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Vakio"
@@ -2259,20 +2257,24 @@ msgid "Property:"
msgstr "Ominaisuus:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(arvo)"
+msgstr "Kiinnitä arvo"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"Arvon kiinnittäminen pakottaa tallentamaan sen, vaikka se olisi sama kuin "
+"oletusarvo."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
+"Kiinnitä arvo [Poistettu käytöstä, koska '%s' on käytössä vain editorissa]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Aseta %s"
@@ -2283,26 +2285,23 @@ msgstr "Aseta useita:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Kiinnitetty %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "Poistettu kiinnitys %s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Kopioi ominaisuudet"
+msgstr "Kopioi ominaisuus"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Liitä ominaisuudet"
+msgstr "Liitä ominaisuus"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Kopioi skriptin polku"
+msgstr "Kopioi ominaisuuden polku"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3024,8 +3023,9 @@ msgid "Install Android Build Template..."
msgstr "Asenna Androidin käännösmalli..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Avaa projektin datakansio"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Avaa editorin datakansio"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3114,7 +3114,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "Pakota varasävyttimien käyttö"
#: editor/editor_node.cpp
msgid ""
@@ -3125,6 +3125,12 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"Kun tämä valinta on päällä, sävyttimet käyttävät varasävytintään (joko "
+"näkyvissä ubersävyttimenä tai piilotettuna) aina ajon aikana.\n"
+"Tämä on hyödyllistä normaalisti pikaisesti näytettävien varasävyttimien "
+"ulkonäön ja tehokkuuden varmistamiseksi.\n"
+"Asynkroninen sävyttimien kääntäminen täytyy olla päällä projektin "
+"asetuksissa, jotta tällä valinnalla olisi vaikutusta."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3183,10 +3189,6 @@ msgid "Toggle Fullscreen"
msgstr "Siirry koko näytön tilaan"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Aseta järjestelmäkonsolin näkyvyys päälle/pois"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Avaa editorin data/asetuskansio"
@@ -3416,6 +3418,7 @@ msgid "Load Errors"
msgstr "Latausvirheet"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Valitse"
@@ -3492,7 +3495,6 @@ msgid "Author"
msgstr "Tekijä"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Tila"
@@ -3738,6 +3740,12 @@ msgstr "Skenen polku:"
msgid "Import From Node:"
msgstr "Tuo solmusta:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Virhe"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Avaa kansio, joka sisältää nämä vientimallit."
@@ -4277,9 +4285,8 @@ msgid "Replace..."
msgstr "Korvaa..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Korvaa kaikki"
+msgstr "Korvaa tiedostoissa"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4290,9 +4297,8 @@ msgid "Replace: "
msgstr "Korvaa: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Korvaa kaikki"
+msgstr "Korvaa kaikki (EI VOI KUMOTA)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4521,6 +4527,8 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Valitse resurssitiedosto tiedostojärjestelmästä tai tarkastelijasta "
+"säätääksesi tuontiasetuksia."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4629,6 +4637,7 @@ msgid "Subfolder:"
msgstr "Alikansio:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Tekijä:"
@@ -5984,9 +5993,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt+Vedä: Siirrä valittua solmua."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+Vedä: Siirrä valittua solmua."
+msgstr "Alt+Vedä: Skaalaa valittua solmua."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6020,7 +6028,7 @@ msgstr "Skaalaustila"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Shift: Skalaa suhteellisesti."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6119,9 +6127,8 @@ msgstr "Lukitse valitut objektit paikalleen (ei voi liikutella)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Lukitse valitut"
+msgstr "Lukitse valitut solmut"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6130,9 +6137,8 @@ msgstr "Poista valittujen objektien lukitus (voi liikutella)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Vapauta valitut"
+msgstr "Vapauta valitut solmut"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6141,9 +6147,8 @@ msgstr "Varmistaa, ettei objektin alisolmuja voi valita."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Ryhmitä valitut"
+msgstr "Ryhmitä valitut solmut"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6152,9 +6157,8 @@ msgstr "Palauttaa objektin aliobjektien mahdollisuuden tulla valituksi."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Poista ryhmitys valituilta"
+msgstr "Poista ryhmitys valituilta solmuilta"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6327,6 +6331,7 @@ msgid "Zoom to 1600%"
msgstr "Aseta lähennystasoksi 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Lisää %s"
@@ -7800,9 +7805,8 @@ msgid "Find in Files..."
msgstr "Etsi tiedostoista..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Korvaa..."
+msgstr "Korvaa tiedostoissa..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -8330,16 +8334,15 @@ msgstr "Kytke liikkuminen päälle/pois"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "Kavenna näkymäkenttää"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "Laajenna näkymäkenttää"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "Palauta oletusarvoihin"
+msgstr "Palauta näkymäkenttä oletusarvoon"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9067,22 +9070,19 @@ msgstr "Lisää tyyppi"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "Suodata tyyppien luetteloa tai luo uusi mukautettu tyyppi:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "Saatavilla olevat profiilit:"
+msgstr "Saatavilla olevat Node-pohjaiset tyypit:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "Tiedostonimi on tyhjä."
+msgstr "Tyypin nimi on tyhjä!"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Haluatko varmasti avata useamman kuin yhden projektin?"
+msgstr "Haluatko varmasti luoda tyhjän tyypin?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9705,7 +9705,8 @@ msgid "TileSet"
msgstr "Laattavalikoima"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "VCS-lisäosia ei ole saatavilla."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9713,16 +9714,56 @@ msgid "Error"
msgstr "Virhe"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Tiedostoja ei ole lisätty valmisteluun"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nimeä ei annettu."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Vahvista muutos"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS-lisäosaa ei ole alustettu"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Sävytinmuutokset:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Sävytinmuutokset:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Vahvista muutos"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Alipuu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Haluatko varmasti luoda tyhjän tyypin?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Tee palautus"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9733,16 +9774,148 @@ msgid "Initialize"
msgstr "Alusta"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Valmistelualue"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Poista piste"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Nimeä uudelleen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Havaitse uudet muutokset"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Muutokset"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Sulje ja tallenna muutokset?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Varastoidaan paikalliset muutokset..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materiaalimuutokset:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Vahvista muutokset"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Vahvista muutokset"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Vahvista muutos"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Osumat:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Luo uusi projekti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Poista animaatioraita"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Etäinen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Luo uusi projekti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Poista"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Etäinen "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Etäinen "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Lähde Mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9761,30 +9934,23 @@ msgid "Typechange"
msgstr "Tyyppimuunnos"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Valmistele valitut"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Valmistele kaikki"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Vahvista muutokset"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Katso tiedostojen eroavaisuudet ennen niiden vahvistamista viimeisimpään "
-"versioon"
+#, fuzzy
+msgid "View:"
+msgstr "Näytä"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Mitään tiedostovertailua ei ole aktiivisena"
+#, fuzzy
+msgid "Split"
+msgstr "Puolita polku"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Havaitse muutokset tiedostovertailussa"
+#, fuzzy
+msgid "Unified"
+msgstr "Muutettu"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -11928,6 +12094,10 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ei voida tallentaa haaraa, joka on skenen ilmentymän alisolmu.\n"
+"Tallentaaksesi tämän haaran omaksi skeneksi, avaa alkuperäinen skene, "
+"napsauta hiiren oikealla painikkella kyseistä haaraa ja valitse \"Tallenna "
+"haara skenenä\"."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11935,6 +12105,10 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ei voida tallentaa haaraa, joka on periytetyn skenen alisolmu.\n"
+"Tallentaaksesi tämän haaran omaksi skeneksi, avaa alkuperäinen skene, "
+"napsauta hiiren oikealla painikkella kyseistä haaraa ja valitse \"Tallenna "
+"haara skenenä\"."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -12474,6 +12648,7 @@ msgid "Export list to a CSV file"
msgstr "Vie lista CSV tiedostoon"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Resurssipolku"
@@ -13323,6 +13498,40 @@ msgstr "Päivitä kaaviokuva"
msgid "Edit Member"
msgstr "Muokkaa jäsentä"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Aseta lauseke"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animaatio"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Syötetyyppi ei ole iteroitavissa: "
@@ -13335,6 +13544,88 @@ msgstr "Iteraattori muuttui epäkelvoksi"
msgid "Iterator became invalid: "
msgstr "Iteraattori muuttui epäkelvoksi: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Nimetään kansio uudelleen:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Nyökkäyskulma:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tyypit:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Itse"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Merkissä %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Lisää %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Aseta %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Kiinnitetty %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Hae %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Virheellinen osoitinominaisuuden nimi."
@@ -13351,6 +13642,21 @@ msgstr "Polku ei johda solmuun!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Virheellinen osoitinominaisuuden nimi '%s' solmussa %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Aseta %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funktiot"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Muuta taulukon kokoa"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Virheellinen argumentti tyyppiä: "
@@ -13360,6 +13666,10 @@ msgid ": Invalid arguments: "
msgstr ": Virheelliset argumentit: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet ei löytynyt skriptistä: "
@@ -13368,6 +13678,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet ei löytynyt skriptistä: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Lataa uudelleen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z-indeksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z-indeksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Vakio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Vakio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Vakio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Vakio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "GDNative singleton on otettu käyttöön"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Ajanhakusolmu"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Skenepuun muokkaus"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Itse"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Leikkaa solmut"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Mukautetulla solmulla ei ole _step() metodia, graafia ei voida käsitellä."
@@ -13380,13 +13750,75 @@ msgstr ""
"Virheellinen paluuarvo _step() metodilta, täytyy olla kokonaisluku (seq out) "
"tai merkkijono (virhe)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Kutsuja"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Vakiot"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Käytä paikallisavaruutta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Käytä paikallisavaruutta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Toiminto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Hae VisualScriptistä"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Hae %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Siirrä ruutua"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fysiikkaruutujen %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaali"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaali"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Luo ilmentymä"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13998,12 +14430,15 @@ msgstr "Tämän peittäjän peittopolygoni on tyhjä. Ole hyvä ja piirrä polyg
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
msgstr ""
+"NavigationAgent2D solmua voidaan käyttää ainoastaan Node2D solmun alla."
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
"The NavigationObstacle2D only serves to provide collision avoidance to a "
"Node2D object."
msgstr ""
+"NavigationObstacle2D on olemassa ainoastaan tarjotakseen Node2D objektille "
+"törmäyksen välttämistä."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -14029,15 +14464,25 @@ msgstr ""
"alla."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU-pohjaiset partikkelit eivät ole tuettuja GLES2 näyttöajurilla.\n"
"Käytä sen sijaan CPUParticles2D solmua. Voit käyttää \"Muunna "
"CPUPartikkeleiksi\" toimintoa tähän tarkoitukseen."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14267,7 +14712,7 @@ msgstr ""
#: scene/3d/navigation_agent.cpp
msgid "The NavigationAgent can be used only under a spatial node."
-msgstr ""
+msgstr "NavigationAgent solmua voidaan käyttää ainoastaan Spatial solmun alla."
#: scene/3d/navigation_mesh_instance.cpp
msgid ""
@@ -14282,6 +14727,8 @@ msgid ""
"The NavigationObstacle only serves to provide collision avoidance to a "
"spatial object."
msgstr ""
+"NavigationObstacle on olemassa ainoastaan tarjotakseen Spatial objektille "
+"törmäyksen välttämistä."
#: scene/3d/occluder.cpp
msgid "No shape is set."
@@ -14292,10 +14739,11 @@ msgid "Only uniform scales are supported."
msgstr "Vain uniform-skaalat ovat tuettuja."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPU-pohjaiset partikkelit eivät ole tuettuja GLES2 näyttöajurilla.\n"
"Käytä sen sijaan CPUParticles solmua. Voit käyttää \"Muunna CPUPartikkeleiksi"
@@ -14303,6 +14751,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Mitään ei näy, koska mesheille ei ole asetettu piirtopyyhkäisyjä (draw "
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 3993213b38..200793ff14 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -366,6 +366,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -816,6 +817,7 @@ msgstr "Maglagay"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -865,8 +867,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1892,7 +1893,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2009,7 +2009,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2178,7 +2179,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2209,6 +2210,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2904,7 +2907,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3039,10 +3042,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3262,6 +3261,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3339,7 +3339,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3565,6 +3564,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Salamin"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4426,6 +4431,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6076,6 +6082,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9376,7 +9383,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9384,7 +9391,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9392,7 +9404,37 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Baguhin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komunidad"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9404,7 +9446,36 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Ilipat Ang Mga Bezier Points"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Username"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9412,48 +9483,132 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Burahin ang (mga) Napiling Key"
+msgid "Commit List"
+msgstr "Komunidad"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Commit list size"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "20"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Ilipat Ang Mga Bezier Points"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Alisin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Ilipat Ang Mga Bezier Points"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Alisin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11966,6 +12121,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12801,6 +12957,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Pagulit ng Animation"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12813,6 +13002,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12829,6 +13092,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Mga Functions:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Baguhin ang Laki ng Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12838,6 +13115,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12846,6 +13127,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Mag-insert ng Key dito"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12855,12 +13185,65 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Mga Functions:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13422,7 +13805,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13635,7 +14027,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index ae81d3dbdd..722d9bdbf8 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -73,7 +73,7 @@
# Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020.
# LaurentOngaro <laurent@gameamea.com>, 2020.
# Julien Humbert <julroy67@gmail.com>, 2020.
-# Nathan <bonnemainsnathan@gmail.com>, 2020, 2021.
+# Nathan <bonnemainsnathan@gmail.com>, 2020, 2021, 2022.
# Léo Vincent <l009.vincent@gmail.com>, 2020.
# Joseph Boudou <joseph.boudou@matabio.net>, 2020.
# Vincent Foulon <vincent.foulon80@gmail.com>, 2020.
@@ -90,8 +90,8 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2022-01-03 03:55+0000\n"
-"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -441,6 +441,7 @@ msgstr "Créer %d NOUVELLES pistes et insérer des clés ?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -916,6 +917,7 @@ msgstr "Ajouter"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -967,8 +969,7 @@ msgstr "Impossible de connecter le signal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1575,7 +1576,7 @@ msgstr "Nom invalide."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Ne peut pas commencer par un chiffre."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -2045,7 +2046,6 @@ msgid "New Folder..."
msgstr "Nouveau dossier..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Rafraîchir"
@@ -2162,7 +2162,8 @@ msgstr "Répertoires et fichiers :"
msgid "Preview:"
msgstr "Aperçu :"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fichier :"
@@ -2212,9 +2213,8 @@ msgid "Properties"
msgstr "Propriétés"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "redéfinition :"
+msgstr "écrase %s :"
#: editor/editor_help.cpp
msgid "default:"
@@ -2337,7 +2337,7 @@ msgstr "Méthode"
msgid "Signal"
msgstr "Signaux"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2368,6 +2368,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Définir %s"
@@ -2378,26 +2380,23 @@ msgstr "Définir plusieurs :"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Épinglé %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "Désépinglé %s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Copier les propriétés"
+msgstr "Copier la propriété"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Coller les propriétés"
+msgstr "Coller la propriété"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Copier le chemin du script"
+msgstr "Copier le chemin de la propriété"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3139,8 +3138,9 @@ msgid "Install Android Build Template..."
msgstr "Installer un modèle de compilation Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Ouvrir le dossier de données du projets"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Ouvrir le dossier de données de l'éditeur"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3301,10 +3301,6 @@ msgid "Toggle Fullscreen"
msgstr "Activer/Désactiver le plein écran"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Activer/désactiver la console système"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Ouvrir le dossier de données/paramètres de l'éditeur"
@@ -3536,6 +3532,7 @@ msgid "Load Errors"
msgstr "Erreurs de chargement"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Sélectionner"
@@ -3612,7 +3609,6 @@ msgid "Author"
msgstr "Auteur"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "État"
@@ -3857,6 +3853,12 @@ msgstr "Chemin de la scène :"
msgid "Import From Node:"
msgstr "Importer à partir d'un nœud :"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Erreur"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Ouvrir le dossier contenant ces modèles."
@@ -4405,9 +4407,8 @@ msgid "Replace..."
msgstr "Remplacer…"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Remplacer tout"
+msgstr "Remplacer dans les fichiers"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4418,9 +4419,8 @@ msgid "Replace: "
msgstr "Remplacer : "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Remplacer tout"
+msgstr "Remplacer tout (IRRÉVERSIBLE)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4756,6 +4756,7 @@ msgid "Subfolder:"
msgstr "Sous-dossier :"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Auteur :"
@@ -6120,9 +6121,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt + Glisser : Déplacer le nœud sélectionné."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt + Glisser : Déplacer le nœud sélectionné."
+msgstr "Alt + Glisser : Redimensionner le nœud sélectionné."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6156,7 +6156,7 @@ msgstr "Mode mise à l'échelle"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Maj : Redimensionner proportionnellement."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6255,9 +6255,8 @@ msgstr "Verrouiller l'objet sélectionné (il ne pourra plus être déplacé)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Verrouillage Sélectionné"
+msgstr "Verrouiller le(s) nœud(s) sélectionné(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6266,9 +6265,8 @@ msgstr "Déverrouiller l'objet sélectionné (il pourra être déplacé de nouve
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Déverrouillage Sélectionné"
+msgstr "Déverrouiller le(s) nœud(s) sélectionné(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6277,9 +6275,8 @@ msgstr "Rendre la sélection des enfants de l'objet impossible."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Groupe sélectionné"
+msgstr "Grouper le(s) nœud(s) sélectionné(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6288,9 +6285,8 @@ msgstr "Rendre la sélection des enfants de l'objet de nouveau possible."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Dégrouper Sélectionné"
+msgstr "Dégrouper le(s) nœud(s) sélectionné(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6463,6 +6459,7 @@ msgid "Zoom to 1600%"
msgstr "Zoomer à 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Ajouter %s"
@@ -7950,9 +7947,8 @@ msgid "Find in Files..."
msgstr "Rechercher dans les fichiers…"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Remplacer…"
+msgstr "Remplacer dans les fichiers…"
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -9238,14 +9234,12 @@ msgid "Available Node-based types:"
msgstr "Profils disponibles :"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "Le nom de fichier est vide."
+msgstr "Le nom du type est vide !"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Voulez-vous vraiment ouvrir plus d'un projet à la fois ?"
+msgstr "Voulez-vous vraiment créer plus un type vide ?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9871,7 +9865,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Aucun addon VCS n'est disponible."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9879,16 +9874,56 @@ msgid "Error"
msgstr "Erreur"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Aucun fichier à ajouter"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Aucun nom renseigné."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Enregistrer"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS Addon n'est pas initialisé"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Changements de shader :"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Changements de shader :"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Enregistrer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Sous-arbre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Voulez-vous vraiment créer plus un type vide ?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Appliquer la réinitialisation"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9899,16 +9934,148 @@ msgid "Initialize"
msgstr "Initialiser"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Zone de transit"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Supprimer un point"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renommer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Détecter de nouveaux changements"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Modifications"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Quitter et sauvegarder les modifications ?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Stockage des modifications locales…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Changements de matériau :"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commiter les changements"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commiter les changements"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Enregistrer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Correspondances :"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Créer un nouveau projet"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Supprimer la piste d’animation"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Distant"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Créer un nouveau projet"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Supprimer l'item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Distant "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Distant "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Maillage source :"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9927,30 +10094,23 @@ msgid "Typechange"
msgstr "Changement de type"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Étape sélectionnée"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Tout ajouter"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commiter les changements"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Vérifier les différences de fichier avant de les soumettre à la dernière "
-"version"
+#, fuzzy
+msgid "View:"
+msgstr "Affichage"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Aucun fichier diff n'est actif"
+#, fuzzy
+msgid "Split"
+msgstr "Diviser le chemin"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Détecter les changements dans le fichier diff"
+#, fuzzy
+msgid "Unified"
+msgstr "Modifié"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12664,6 +12824,7 @@ msgid "Export list to a CSV file"
msgstr "Exporter la liste vers un fichier CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Chemin de ressource"
@@ -13516,6 +13677,40 @@ msgstr "Rafraîchir le graphique"
msgid "Edit Member"
msgstr "Modifier le membre"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Définir l'expression"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animation"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Type d'entrée non itérable : "
@@ -13528,6 +13723,88 @@ msgstr "L'itérateur est devenu invalide"
msgid "Iterator became invalid: "
msgstr "L'itérateur est devenu invalide : "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renommer le dossier :"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Tangage :"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Types :"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Self"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Au caractère %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Ajouter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Définir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Épinglé %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Obtenir %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Indice de nom de propriété invalide."
@@ -13544,6 +13821,21 @@ msgstr "Le chemin ne mène pas au nœud !"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nom de propriété invalide « %s » dans le nœud %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Définir %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Fonctions"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionner le tableau"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argument invalide de type : "
@@ -13553,6 +13845,10 @@ msgid ": Invalid arguments: "
msgstr ": Arguments invalides : "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet introuvable dans le script : "
@@ -13561,6 +13857,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet introuvable dans le script : "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Recharger"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Activé le Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nœud TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Édition de l'arbre de scène"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Self"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Couper les nœuds"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Le nœud personnalisé n'a pas de méthode _step(), le graph ne peut pas être "
@@ -13574,13 +13930,75 @@ msgstr ""
"La valeur retournée par _step() est invalide, elle doit être un entier (seq "
"out), ou une chaîne (erreur)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Appels"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Utiliser les coordonées locales"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Utiliser les coordonées locales"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Action"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Rechercher VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Obtenir %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Déplacer le cadre"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Image physique %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaux"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaux"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instance"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14255,16 +14673,26 @@ msgstr ""
"d'un nœud de type ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Les particules de type GPU ne sont pas supportées par le pilote graphique "
"GLES2.\n"
"Utilisez le nœud CPUParticles2D à la place. Vous pouvez utiliser l'option « "
"Convertir en CPUParticles » pour ce faire."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14522,10 +14950,11 @@ msgid "Only uniform scales are supported."
msgstr "Seules les échelles uniformes sont prises en charge."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Les particules de type GPU ne sont pas supportées par le pilote graphique "
"GLES2.\n"
@@ -14534,6 +14963,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Rien n'est visible car les maillages n'ont pas été assignés au tirage des "
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index d0e6734463..03611eed78 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -357,6 +357,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -807,6 +808,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -856,8 +858,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1883,7 +1884,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2000,7 +2000,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2169,7 +2170,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2199,6 +2200,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2893,7 +2896,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3028,10 +3031,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3248,6 +3247,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3324,7 +3324,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3549,6 +3548,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4407,6 +4411,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6053,6 +6058,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9344,7 +9350,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9352,7 +9358,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9360,7 +9371,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9372,7 +9411,36 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Ainm nua:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9380,49 +9448,131 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Ainm nua:"
+msgid "Create New Branch"
+msgstr "Cruthaigh"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Scrios ionchur"
+msgid "Create New Remote"
+msgstr "Cruthaigh"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Remove Remote"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Remote Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Remote URL"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Ainm nua:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Scrios ionchur"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11935,6 +12085,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12768,6 +12919,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "CrannBeochan"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12780,6 +12964,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12796,6 +13054,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Cruthaigh"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12805,6 +13076,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12813,6 +13088,56 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nód Cumaisc2"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Cruthaigh"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12822,12 +13147,65 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Cruthaigh"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13390,7 +13768,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13603,7 +13990,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/gl.po b/editor/translations/gl.po
index 02e2a982b8..f98288945e 100644
--- a/editor/translations/gl.po
+++ b/editor/translations/gl.po
@@ -360,6 +360,7 @@ msgstr "Crear %d novas pistas e engadir chaves?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -829,6 +830,7 @@ msgstr "Engadir"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -880,8 +882,7 @@ msgstr "No se pode conectar a sinal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1960,7 +1961,6 @@ msgid "New Folder..."
msgstr "Novo Cartafol..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Actualizar"
@@ -2077,7 +2077,8 @@ msgstr "Directorios e Arquivos:"
msgid "Preview:"
msgstr "Vista Previa:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Arquivo:"
@@ -2254,7 +2255,7 @@ msgstr "Método"
msgid "Signal"
msgstr "Sinal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2285,6 +2286,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3047,8 +3050,9 @@ msgid "Install Android Build Template..."
msgstr "Instalar plantilla de compilación de Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Abrir Cartafol de Datos do Proxecto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Abrir Cartafol de Datos do Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3206,10 +3210,6 @@ msgid "Toggle Fullscreen"
msgstr "Act./Desact. Pantalla Completa"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Act./Desact. Consola do Sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Abrir Cartafol de Datos/Configuración do Editor"
@@ -3433,6 +3433,7 @@ msgid "Load Errors"
msgstr "Erros durante a Carga"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Elixir"
@@ -3513,7 +3514,6 @@ msgid "Author"
msgstr "Autores"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Estado"
@@ -3751,6 +3751,12 @@ msgstr "Ruta da Escena:"
msgid "Import From Node:"
msgstr "Importar Desde Nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Erro"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4640,6 +4646,7 @@ msgid "Subfolder:"
msgstr "Subcartafol:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6322,6 +6329,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Engadir %s"
@@ -9743,7 +9751,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9751,18 +9759,58 @@ msgid "Error"
msgstr "Erro"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nome non proporcionado."
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Cambios"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Comunidade"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subárbore"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Está seguro de que quere abrir máis dun proxecto?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Restablecer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9771,7 +9819,37 @@ msgid "Initialize"
msgstr "Inicializar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Eliminar Punto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renomear"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9779,49 +9857,143 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Cambios"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Parámetro Cambiado"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr "Modificado"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Gardando cambios locales..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
-msgstr "Renomeado"
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Parámetro Cambiado"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
-msgstr "Eliminado"
+msgid "Commit Message"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Comunidade"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "20"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Branches"
+msgstr "Coincidencias:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Crear Novo Proxecto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Eliminar Pista de Animación"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Crear Novo Proxecto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Eliminar Elemento"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
msgstr ""
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr "Modificado"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr "Renomeado"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Eliminado"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Ver"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unified"
+msgstr "Modificado"
+
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
msgstr ""
@@ -12433,6 +12605,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13268,6 +13441,39 @@ msgstr ""
msgid "Edit Member"
msgstr "Editar Membro"
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animación"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13280,6 +13486,86 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renomeando Cartafol:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Cabeceo"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipo:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Engadir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Engadir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13296,6 +13582,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funcións"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionar Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13305,6 +13605,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13313,6 +13617,65 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Recargar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ãndice:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ãndice:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Eliminar Nodo"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edición de Ãrbore de Escenas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Propio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Cortar Nodos"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13322,14 +13685,76 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Chamadas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usar Espazo Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usar Espazo Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Acción"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Buscar en VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Seguinte pestana"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fotograma de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instanciar"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13929,16 +14354,26 @@ msgid ""
msgstr ""
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"As partículas baseadas na GPU non están soportas por o controlador de vídeo "
"de GLES2.\n"
"Usa o nodo CPUParticles2D no seu lugar. Podes usar a opción \"Converter a "
"CPUParticles\" con tal motivo."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14166,10 +14601,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"As partículas baseadas na GPU non están soportas por o controlador de vídeo "
"de GLES2.\n"
@@ -14178,6 +14614,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 3c2ce4ff95..73da4945f9 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -376,6 +376,7 @@ msgstr "×”×× ×œ×™×¦×•×¨ %d רצועות חדשות ולהכניס מפתחות
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -837,6 +838,7 @@ msgstr "הוספה"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -886,8 +888,7 @@ msgstr "×ין ×פשרות לחבר ×ות"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1937,7 +1938,6 @@ msgid "New Folder..."
msgstr "תיקייה חדשה…"
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "רענון"
@@ -2054,7 +2054,8 @@ msgstr "תיקיות וקבצי×:"
msgid "Preview:"
msgstr "תצוגה מקדימה:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "קובץ:"
@@ -2228,7 +2229,7 @@ msgstr "מתודה"
msgid "Signal"
msgstr "×ות"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "קבוע"
@@ -2259,6 +2260,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "קביעת %s"
@@ -2992,8 +2995,9 @@ msgid "Install Android Build Template..."
msgstr "התקנת תבנית בנייה ל×נדרו×יד..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "פתיחת תיקיית נתוני המיז×"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "פתיחת תיקיית נתוני העורך"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3146,10 +3150,6 @@ msgid "Toggle Fullscreen"
msgstr "הפעלת/ביטול מסך מל×"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "הפעלת/ביטול מסוף מערכת"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "פתיחת תיקיית נתוני/הגדרות העורך"
@@ -3380,6 +3380,7 @@ msgid "Load Errors"
msgstr "שגי×ות טעינה"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "בחירה"
@@ -3461,7 +3462,6 @@ msgid "Author"
msgstr "יוצרי×"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3694,6 +3694,12 @@ msgstr "נתיב סצנות:"
msgid "Import From Node:"
msgstr "×™×™×‘×•× ×ž×ž×¤×¨×§:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "שגי××”!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4622,6 +4628,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "יוצר:"
@@ -6358,6 +6365,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9889,7 +9897,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9897,19 +9905,58 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "×œ× ×¦×•×™×Ÿ ש×."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "קהילה"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "שינויי חומרי×"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "שינויי חומרי×"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "קהילה"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "×”×× ×תה בטוח ש×תה רוצה להסיר ×ת כל ×”×—×™×‘×•×¨×™× ×ž×”×ות ×”×–×”?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "החל ×יפוס"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9919,7 +9966,37 @@ msgid "Initialize"
msgstr "הגדלת ×ות ר×שונה"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "הסרת נקודה בנתיב"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "שינוי ש×"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9929,53 +10006,146 @@ msgstr "יצירת %s חדש"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "שינוי"
+msgid "Discard all changes"
+msgstr "לסגור ולשמור ×ת השינויי×?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "×”×©×™× ×•×™×™× ×”×ž×§×•×ž×™×™× ×ž×וחסני×…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "שינויי חומרי×"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "סנכרון ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "סנכרון ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "קהילה"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "שינוי ש×"
+msgid "Branches"
+msgstr "הת×מות:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "למחוק"
+msgid "Create New Branch"
+msgstr "יצירת %s חדש"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "שינוי"
+msgid "Remove Branch"
+msgstr "מחיקת רצועת הנפשה"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "מחובר"
+msgid "Remotes"
+msgstr "מרוחק"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "לשמור הכול"
+msgid "Create New Remote"
+msgstr "יצירת %s חדש"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "סנכרון ×”×©×™× ×•×™×™× ×‘×¡×§×¨×™×¤×˜"
+msgid "Remove Remote"
+msgstr "הסרת תבנית"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "מרוחק "
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Remote URL"
+msgstr "מרוחק "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "Force Push"
+msgstr "נתיב המש×ב"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "שינוי ש×"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "למחוק"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "שינוי"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "תצוגה מקדימה:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "פיצול נתיב"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12588,6 +12758,7 @@ msgid "Export list to a CSV file"
msgstr "×™×™×¦×•× ×¨×©×™×ž×” לקובץ CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "נתיב המש×ב"
@@ -13435,6 +13606,40 @@ msgstr "רענון תרשי×"
msgid "Edit Member"
msgstr "עריכת שדה"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "גרסה נוכחית:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "הנפשה"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "סוג הקלט ×œ× ×–×ž×™×Ÿ למחזוריות: "
@@ -13447,6 +13652,85 @@ msgstr "×יטרטור הפך ×œ×œ× ×—×•×§×™"
msgid "Iterator became invalid: "
msgstr "×יטרטור הפך ×œ×œ× ×—×•×§×™: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "שינוי ×©× ×”×ª×™×§×™×™×”:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "סוג"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "עצמי"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "×ª×•×•×™× ×ª×§×¤×™×:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "קביעת %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "קבלת %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "×©× ×ž×פיין ×”×ינדקס שגוי."
@@ -13463,6 +13747,21 @@ msgstr "הנתיב ×œ× ×ž×•×‘×™×œ מפרק!"
msgid "Invalid index property name '%s' in node %s."
msgstr "×©× ×ž×פיין ×ינדקס ×œ× ×—×•×§×™ '%s' במפרק %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "קביעת %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "פונקציות"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "שינוי גודל המערך"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": ×רגומנט שגוי מסוג: "
@@ -13472,6 +13771,10 @@ msgid ": Invalid arguments: "
msgstr ": ××¨×’×•×ž× ×˜×™× ×©×’×•×™×™×: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "×œ× × ×ž×¦× VariableGet בסקריפט: "
@@ -13480,6 +13783,66 @@ msgid "VariableSet not found in script: "
msgstr "×œ× × ×ž×¦× VariableSet בסקריפט: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "רענון"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "×”×–×—×” ×וטומטית"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "×”×–×—×” ×וטומטית"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "קבוע"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "קבוע"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "קבוע"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "קבוע"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "סינגלטון GDNative מ×ופשר"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "מפרק TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "עריכת עץ הסצנות"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "עצמי"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "גזירת מפרקי×"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "למפרק המות×× ×ין שיטת ‎_step()‎, ×ין ×פשרות לעבד תרשי×."
@@ -13490,13 +13853,75 @@ msgid ""
msgstr ""
"ערך מוחזר ×œ× ×—×•×§×™ מ-_step(), חייב להיות מספר ×©×œ× (seq out) ×ו מחרוזת (שגי××”)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "קרי×ות"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "קבועי×"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "מצב מרחב מקומי (%s)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "מצב מרחב מקומי (%s)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "כל הבחירה"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "חיפוש VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "קבלת %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "מצב הזזה (W)"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "שקופית פיזיקלית %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "×ות"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "×ות"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "עותק"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14122,15 +14547,25 @@ msgstr ""
"מפרק ParallaxLayer עובד רק ×›×שר ×”×•× ×ž×•×’×“×¨ כצ××¦× ×©×œ מפרק ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"×—×œ×§×™×§×™× ×ž×‘×•×¡×¡×™ GPU ××™× × × ×ª×ž×›×™× ×¢×œ-ידי מנהל וויד×ו GLES2.\n"
"השתמש בצומת CPUParticles2D במקו×. למטרה זו ×”×פשרות \"המר ×œ×—×œ×§×™×§×™× ×©×œ CPU\" "
"קיימת."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14367,10 +14802,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"×—×œ×§×™×§×™× ×ž×‘×•×¡×¡×™ GPU ××™× × × ×ª×ž×›×™× ×¢×œ-ידי מנהל וויד×ו GLES2.\n"
"השתמש בצומת CPUParticles במקו×. למטרה זו ×”×פשרות \"המר ×œ×—×œ×§×™×§×™× ×©×œ CPU\" "
@@ -14378,6 +14814,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "×©×•× ×“×‘×¨ ×ינו גלוי ×›×™ רשתות ×œ× ×”×•×§×¦×• למעברי ההדפסה."
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 29d59d3ee1..65e129c224 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -369,6 +369,7 @@ msgstr "% D नठटà¥à¤°à¥ˆà¤• बनाà¤à¤‚ और कà¥à¤‚जियाà
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -835,6 +836,7 @@ msgstr "जोड़िये"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -886,8 +888,7 @@ msgstr "इशारा कनेकà¥à¤Ÿ नहीं कर सकते"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1957,7 +1958,6 @@ msgid "New Folder..."
msgstr "नया फ़ोलà¥à¤¡à¤°..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "रिफ़à¥à¤°à¥‡à¤¶"
@@ -2074,7 +2074,8 @@ msgstr "डायरेकà¥à¤Ÿà¤°à¤¿à¤œ & फ़ाइले:"
msgid "Preview:"
msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "फ़ाइल:"
@@ -2248,7 +2249,7 @@ msgstr "मेथड"
msgid "Signal"
msgstr "सिगà¥à¤¨à¤²"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
@@ -2279,6 +2280,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3016,8 +3019,9 @@ msgid "Install Android Build Template..."
msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डेटा फ़ोलà¥à¤¡à¤° खोलिये"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "संपादक डेटा फ़ोलà¥à¤¡à¤° खोलें"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3173,10 +3177,6 @@ msgid "Toggle Fullscreen"
msgstr "पूरà¥à¤£à¤¸à¥à¤•à¥à¤°à¥€à¤¨ चालू करें"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "टॉगल सिसà¥à¤Ÿà¤® कंसोल"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "संपादक डेटा / सेटिंगà¥à¤¸ फ़ोलà¥à¤¡à¤° खोलें"
@@ -3409,6 +3409,7 @@ msgid "Load Errors"
msgstr "लोड तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¤¾à¤‚"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "चà¥à¤¨à¥‡à¤‚"
@@ -3489,7 +3490,6 @@ msgid "Author"
msgstr "लेखक"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3726,6 +3726,12 @@ msgstr "दृशà¥à¤¯ पथ:"
msgid "Import From Node:"
msgstr "नोड से आयात:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "पà¥à¤°à¤¤à¤¿à¤®à¤¾"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4625,6 +4631,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "लेखक:"
@@ -6286,6 +6293,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9707,7 +9715,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9715,19 +9723,57 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "कोई नाम पà¥à¤°à¤¦à¤¾à¤¨ नहीं किया गया।"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "समà¥à¤¦à¤¾à¤¯"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "बदली"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "समà¥à¤¦à¤¾à¤¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "कà¥à¤¯à¤¾ आप सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ हैं कि आप इस सिगà¥à¤¨à¤² से सभी कनेकà¥à¤¶à¤¨ हटाना चाहते हैं?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "रीसेट आकार"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9736,7 +9782,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "मिटाना"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "नाम बदली"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9745,50 +9821,143 @@ msgid "Detect new changes"
msgstr "à¤à¤• नया बनाà¤à¤‚"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "लोकल बदलीया सà¥à¤Ÿà¥‹à¤° कर रहा है..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "समà¥à¤¦à¤¾à¤¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "ऑडियो बस का नाम बदलें"
+msgid "Commit List"
+msgstr "समà¥à¤¦à¤¾à¤¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "को हटा दें"
+msgid "Branches"
+msgstr "à¤à¤• जैसा:"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+#, fuzzy
+msgid "Create New Branch"
+msgstr "नया%s बनाà¤à¤‚"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "अनीम टà¥à¤°à¥ˆà¤• निकालें"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "जà¥à¤¡à¤¿à¤¯à¥‡"
+msgid "Remotes"
+msgstr "मिटाइये"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "नया%s बनाà¤à¤‚"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "आइटम निकालें"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "नोड का नाम:"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Remote URL"
+msgstr "मिटाइये"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "ऑडियो बस का नाम बदलें"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "को हटा दें"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "पूरà¥à¤µ दरà¥à¤¶à¤¨:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "नोड वकà¥à¤° संपादित करें"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12357,6 +12526,7 @@ msgid "Export list to a CSV file"
msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13212,6 +13382,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "à¤à¤¨à¤¿à¤®à¥‡à¤¶à¤¨"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13224,6 +13427,82 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "फ़ोलà¥à¤¡à¤° का नाम बदल रहे है:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "सà¥à¤µà¤¯à¤‚"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13240,6 +13519,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "कारà¥à¤¯à¥‹à¤‚"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Array को बड़ा या छोटा करना"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13249,6 +13542,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13257,6 +13554,63 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "पà¥à¤¨à¤ƒ लोड करें"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "नोड हटाà¤à¤‚"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "सीन टà¥à¤°à¥€ à¤à¤¡à¤¿à¤Ÿà¤¿à¤‚ग"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "सà¥à¤µà¤¯à¤‚"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "पà¥à¤°à¤¤à¤¿à¤²à¤¿à¤ªà¤¿"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13266,14 +13620,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "कॉल"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "कोनà¥à¤¸à¥à¤Ÿà¤¨à¥à¤Ÿ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "कारà¥à¤¯"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "अगला टैब"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "फिजिकà¥à¤¸ फà¥à¤°à¥‡à¤® %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "सिगà¥à¤¨à¤²"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "सिगà¥à¤¨à¤²"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "इनसà¥à¤Ÿà¤¨à¥à¤¸"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13858,7 +14272,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14073,7 +14496,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index a5279a9099..b722aa151a 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -359,6 +359,7 @@ msgstr "Napravi %d NOVIH staza i umetni kljuÄeve?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -814,6 +815,7 @@ msgstr "Dodaj"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -863,8 +865,7 @@ msgstr "Ne mogu spojiti signal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1910,7 +1911,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2027,7 +2027,8 @@ msgstr "Direktoriji i datoteke:"
msgid "Preview:"
msgstr "Pregled:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Datoteka:"
@@ -2195,7 +2196,7 @@ msgstr "Metoda"
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2226,6 +2227,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2922,8 +2925,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr ""
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Otvori datoteku"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3058,10 +3062,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3280,6 +3280,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3358,7 +3359,6 @@ msgid "Author"
msgstr "Autori"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3585,6 +3585,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Greška!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4455,6 +4461,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6109,6 +6116,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9425,7 +9433,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9433,7 +9441,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9441,7 +9454,39 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Promijeni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Promijeni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Zajednica"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Jesi li siguran da želiš ukloniti sve veze s ovog signala?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9453,7 +9498,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "ObriÅ¡i Bezier ToÄku"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Preimenuj zvuÄnu sabirnicu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9461,53 +9536,143 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Promjene"
+msgid "Discard all changes"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Promijeni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Preimenuj zvuÄnu sabirnicu"
+msgid "Commit Message"
+msgstr "Promijeni"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Obriši"
+msgid "Commit Changes"
+msgstr "Promijeni"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
+msgid "Commit List"
msgstr "Promijeni"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Brisati odabrani kljuÄ/odabrane kljuÄeve"
+msgid "Branches"
+msgstr "Podudaranja:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Zamijeni sve"
+msgid "Create New Branch"
+msgstr "Napravi novi %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
+msgid "Remove Branch"
+msgstr "Ukloni Stazu Animacije"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Ukloni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Napravi novi %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "ObriÅ¡i Bezier ToÄku"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Naziv ÄŒvora(node):"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Ukloni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Preimenuj zvuÄnu sabirnicu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Obriši"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
msgstr "Promijeni"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "View:"
+msgstr "Pregled:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12027,6 +12192,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12868,6 +13034,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animacija"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12880,6 +13079,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12896,6 +13169,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcije"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12905,6 +13191,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12913,6 +13203,56 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Premjesti Ävor(node)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Kreiraj Scenu"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12922,12 +13262,67 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Funkcije"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Premjesti Okvir"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signal:"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13490,7 +13885,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13703,7 +14107,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 722be28839..9130ef9507 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -377,6 +377,7 @@ msgstr "Létrehoz %d ÚJ sávot és beszúrja a kulcsokat?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -851,6 +852,7 @@ msgstr "Hozzáadás"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -901,8 +903,7 @@ msgstr "Nem lehet csatlakoztatni a jelet"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1974,7 +1975,6 @@ msgid "New Folder..."
msgstr "Új Mappa..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Frissítés"
@@ -2091,7 +2091,8 @@ msgstr "Könyvtárak és Fájlok:"
msgid "Preview:"
msgstr "Előnézet:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fájl:"
@@ -2268,7 +2269,7 @@ msgstr "Metódus"
msgid "Signal"
msgstr "Jelzés"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Ãllandó"
@@ -2299,6 +2300,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3066,8 +3069,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Projektadat-mappa megnyitása"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Szerkesztő Adatmappájának Megnyitása"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3220,10 +3224,6 @@ msgid "Toggle Fullscreen"
msgstr "Teljes Képernyő"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Rendszerkonzol be- és kikapcsolása"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Szerkesztő adatok/beállítások mappa megnyitása"
@@ -3453,6 +3453,7 @@ msgid "Load Errors"
msgstr "Betöltési Hibák"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Kiválasztás"
@@ -3533,7 +3534,6 @@ msgid "Author"
msgstr "Szerzők"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3763,6 +3763,12 @@ msgstr "Scene elérési Út:"
msgid "Import From Node:"
msgstr "Importálás Node-ból:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Hiba!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4664,6 +4670,7 @@ msgid "Subfolder:"
msgstr "Almappa:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Szerző:"
@@ -6353,6 +6360,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "%s Hozzáadása"
@@ -9749,7 +9757,7 @@ msgid "TileSet"
msgstr "Csempekészlet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9757,18 +9765,57 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nincs név megadva."
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Változások"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Változások"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Közösség"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Biztos, hogy egynél több projektet nyit meg?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Visszaállítás"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9777,7 +9824,37 @@ msgid "Initialize"
msgstr "Inicializálás"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Pont eltávolítása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Ãtnevezés"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9785,49 +9862,145 @@ msgid "Detect new changes"
msgstr "Új változások észlelése"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Változások"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Bezárja és menti a változásokat?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr "Módosított"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Helyi módosítások eltárolása..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
-msgstr "Ãtnevezve"
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "A paraméter megváltozott"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
-msgstr "Törölve"
+msgid "Commit Message"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
-msgstr "Típusmódosítás"
+msgid "Commit Changes"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+#, fuzzy
+msgid "Commit List"
+msgstr "Közösség"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "20"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Branches"
+msgstr "Egyezések:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Új Projekt Létrehozása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Animáció Sáv Eltávolítása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "Remotes"
+msgstr "Eltávolítás"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Új Projekt Létrehozása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Elem eltávolítása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Node neve:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Eltávolítás"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Forrás Mesh:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr "Módosított"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr "Ãtnevezve"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Törölve"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr "Típusmódosítás"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Nézet"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Útvonal Felosztása"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unified"
+msgstr "Módosított"
+
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
msgstr ""
@@ -12353,6 +12526,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13199,6 +13373,40 @@ msgstr "Grafikon frissítése"
msgid "Edit Member"
msgstr "Tag szerkesztése"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Kifejezés beállítása"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animáció"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Beviteli típus nem iterálható: "
@@ -13211,6 +13419,86 @@ msgstr "Az iterátor érvénytelenné vált"
msgid "Iterator became invalid: "
msgstr "Az iterátor érvénytelenné vált: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Mappa átnevezése:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Típus:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Saját"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "A(z) %s karakternél"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "%s Hozzáadása"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "%s Hozzáadása"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13227,6 +13515,20 @@ msgstr "Az út nem vezeti a csomópontot!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Érvénytelen index tulajdonság név: '%s' a(z) %s node-ban."
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Függvények"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Tömb átméretezése"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Érvénytelen típusargumentum: "
@@ -13236,6 +13538,10 @@ msgid ": Invalid arguments: "
msgstr ": Érvénytelen argumentumok: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet nem található a szkriptben: "
@@ -13244,6 +13550,65 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet nem található a szkriptben: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Újratöltés"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Ãllandó"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Ãllandó"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Ãllandó"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Ãllandó"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "IdőKereső Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Jelenetfa szerkesztése"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Saját"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Node-ok kivágása"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13253,14 +13618,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Hívások"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Ãllandók"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Művelet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Keret mozgatása"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fizika Keret %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Jelzés"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Jelzés"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Példány"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13840,7 +14265,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14055,7 +14489,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 686536da75..524562bec9 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -391,6 +391,7 @@ msgstr "Buat track BARU %d dan masukkan tombol-tombol?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -859,6 +860,7 @@ msgstr "Tambah"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -909,8 +911,7 @@ msgstr "Tidak dapat menghubungkan sinyal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1974,7 +1975,6 @@ msgid "New Folder..."
msgstr "Buat Direktori..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Segarkan"
@@ -2091,7 +2091,8 @@ msgstr "Direktori-direktori & File-file:"
msgid "Preview:"
msgstr "Pratinjau:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "File:"
@@ -2270,7 +2271,7 @@ msgstr "Fungsi"
msgid "Signal"
msgstr "Sinyal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstan"
@@ -2301,6 +2302,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Setel %s"
@@ -3057,8 +3060,9 @@ msgid "Install Android Build Template..."
msgstr "Pasang Templat Build Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Buka Project Data Manager"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Buka Folder Data Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3215,10 +3219,6 @@ msgid "Toggle Fullscreen"
msgstr "Mode Layar Penuh"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Jungkitkan Konsol Sistem"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Buka Direktori Data/Pengaturan Editor"
@@ -3448,6 +3448,7 @@ msgid "Load Errors"
msgstr "Muat Galat"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Pilih"
@@ -3524,7 +3525,6 @@ msgid "Author"
msgstr "Pencipta"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3768,6 +3768,12 @@ msgstr "Lokasi Skena:"
msgid "Import From Node:"
msgstr "Impor dari Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Galat"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Buka folder yang berisi template ini."
@@ -4649,6 +4655,7 @@ msgid "Subfolder:"
msgstr "Subdirektori:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Pembuat:"
@@ -6340,6 +6347,7 @@ msgid "Zoom to 1600%"
msgstr "Perbesar 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Tambah %s"
@@ -9766,7 +9774,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Tidak ada ekstensi VCS yang tersedia."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9774,16 +9783,56 @@ msgid "Error"
msgstr "Galat"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Tidak ada berkas yang ditambahkan ke staging"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nama masih kosong."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Komit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Pengaya VCS tidak diinisialisasi"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Perubahan Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Perubahan Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subpohon"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Apakah Anda yakin membuka lebih dari satu proyek?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Terapkan Reset"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9794,16 +9843,148 @@ msgid "Initialize"
msgstr "Inisialisasi"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Area staging"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Hapus Titik"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Ubah Nama"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Deteksi perubahan baru"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Perubahan"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Tutup dan simpan perubahan?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Menyimpan perubahan-perubahan lokal..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Perubahan Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Komit Perubahan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Komit Perubahan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Komit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Kecocokan:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Buat Projek Baru"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Hapus Trek Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remot"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Buat Projek Baru"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Hapus item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remot "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remot "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Sumber Mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9822,28 +10003,23 @@ msgid "Typechange"
msgstr "Jenis perubahan"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Stage Hanya yang Dipilih"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Stage Semua"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Komit Perubahan"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Tampilkan perbedaan berkas sebelum mengkomitnya ke versi terbaru"
+#, fuzzy
+msgid "View:"
+msgstr "Pandangan"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Tidak ada berkas diff yang sedang aktif"
+#, fuzzy
+msgid "Split"
+msgstr "Pisahkan Tapak"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Deteksi perubahan dalam berkas diff"
+#, fuzzy
+msgid "Unified"
+msgstr "Dimodifikasi"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12545,6 +12721,7 @@ msgid "Export list to a CSV file"
msgstr "Ekspor daftar ke berkas CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Lokasi Resource"
@@ -13402,6 +13579,40 @@ msgstr "Segarkan Grafik"
msgid "Edit Member"
msgstr "Sunting Anggota"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Tetapkan ekspresi"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animasi"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tipe masukan tidak iterable: "
@@ -13414,6 +13625,88 @@ msgstr "Iterator menjadi tidak sah"
msgid "Iterator became invalid: "
msgstr "Iterator menjadi tidak sah: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Mengubah nama folder dengan:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Dongak:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Jenis:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Sendiri"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Pada karakter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Tambah %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Setel %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Tambah %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Dapatkan %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nama properti index tidak sah."
@@ -13430,6 +13723,21 @@ msgstr "Path tidak menunjukkan Node!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nama properti index '%s' tidak sah dalam node %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Setel %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Fungsi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ubah ukuran Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argumen tidak sah dari tipe: "
@@ -13439,6 +13747,10 @@ msgid ": Invalid arguments: "
msgstr ": Argumen-argumen tidak sah: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet tidak ditemukan dalam script: "
@@ -13447,6 +13759,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet tidak ditemukan dalam script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Muat Ulang"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Indeks Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Indeks Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Aktifkan Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Node TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Menyunting Pohon Skena"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Sendiri"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Potong Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Node modifikasi tidak memiliki method _step(), tidak bisa memproses grafik."
@@ -13459,13 +13831,75 @@ msgstr ""
"Nilai kembali dari _step() tidak sah, seharusnya integer (seq out), atau "
"string (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Panggil"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Gunakan Ruang Lokal"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Gunakan Ruang Lokal"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Aksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Cari VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Dapatkan %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Geser Frame"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Frame Fisika %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instansi"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14104,15 +14538,25 @@ msgstr ""
"node ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Partikel berbasis GPU tidak didukung oleh video driver GLES2.\n"
"Gunakan node CPUParticles2D sebagai gantinya. Anda dapat menggunakan opsi "
"\"Konversikan jadi CPUParticles\" untuk tujuan ini."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14366,10 +14810,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Partikel berbasis GPU tidak didukung oleh driver video GLES2.\n"
"Gunakan CPUParticles saja. Anda dapat menggunakan opsi \"Konversikan ke "
@@ -14377,6 +14822,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Tidak ada yang ditampilkan karena mesh tidak ditetapkan untuk menggambar "
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 99a2daa775..773a89394f 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -380,6 +380,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -842,6 +843,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -891,8 +893,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1923,7 +1924,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2040,7 +2040,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2208,7 +2209,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2238,6 +2239,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2937,7 +2940,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3073,10 +3076,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3295,6 +3294,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3372,7 +3372,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3599,6 +3598,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4460,6 +4464,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6133,6 +6138,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9474,7 +9480,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9482,7 +9488,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9490,7 +9501,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9502,7 +9541,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Fjarlægja val"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Endurnefning Anim track"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9510,50 +9579,135 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Endurnefning Anim track"
+msgid "Create New Branch"
+msgstr "Val á kvarða"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Anim DELETE-lyklar"
+msgid "Remove Branch"
+msgstr "Fjarlægja Anim track"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Val á kvarða"
+msgid "Remotes"
+msgstr "Fjarlægja val"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Create New Remote"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Fjarlægja val"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Fjarlægja val"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Endurnefning Anim track"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Anim DELETE-lyklar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Breyta hnútnum Ferill"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12091,6 +12245,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12939,6 +13094,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Stillið breyting á:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12951,6 +13139,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12967,6 +13229,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Val á kvarða"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12976,6 +13251,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12984,6 +13263,56 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Anim DELETE-lyklar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Tvíteknir lyklar"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12993,12 +13322,66 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Allt úrvalið"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Hreyfa Viðbótar Lykil"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13561,7 +13944,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13774,7 +14166,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 18b4fe4bce..0d2c6a07e6 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -420,6 +420,7 @@ msgstr "Creare %d NUOVE tracce e inserirci i fotogrammi chiavi?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -893,6 +894,7 @@ msgstr "Aggiungi"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -944,8 +946,7 @@ msgstr "Impossibile connettere il segnale"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2018,7 +2019,6 @@ msgid "New Folder..."
msgstr "Nuova cartella..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Aggiorna"
@@ -2135,7 +2135,8 @@ msgstr "File e cartelle:"
msgid "Preview:"
msgstr "Anteprima:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "File:"
@@ -2310,7 +2311,7 @@ msgstr "Metodo"
msgid "Signal"
msgstr "Segnale"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Costante"
@@ -2341,6 +2342,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Imposta %s"
@@ -3107,8 +3110,9 @@ msgid "Install Android Build Template..."
msgstr "Installa il modello di costruzione per Android…"
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Apri la cartella del progetto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Apri la cartella dei dati dell'editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3266,10 +3270,6 @@ msgid "Toggle Fullscreen"
msgstr "Commuta la modalità a schermo intero"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Commuta la console di sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Apri cartella dei dati/impostazioni editor"
@@ -3502,6 +3502,7 @@ msgid "Load Errors"
msgstr "Errori di caricamento"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Seleziona"
@@ -3578,7 +3579,6 @@ msgid "Author"
msgstr "Autore"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Stato"
@@ -3825,6 +3825,12 @@ msgstr "Percorso Scena:"
msgid "Import From Node:"
msgstr "Importa Da Nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Errore"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Apre la cartella che contiene questi modelli."
@@ -4731,6 +4737,7 @@ msgid "Subfolder:"
msgstr "Sottocartella:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autore:"
@@ -6459,6 +6466,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom a 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Aggiungi %s"
@@ -9905,7 +9913,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Non sono disponibili estensioni VCS."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9913,16 +9922,56 @@ msgid "Error"
msgstr "Errore"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Nessun file aggiunto allo stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nessun nome fornito."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "L'Estenzione VCS non è inizializzata"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Cambiamenti degli shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Cambiamenti degli shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Sottoalbero"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Sei sicuro di voler aprire più di un progetto?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Reimposta"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9933,16 +9982,148 @@ msgid "Initialize"
msgstr "Inizializza"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Area di Staging"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Rimuovi punto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Rinomina"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Rileva nuove modifiche"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Cambiamenti"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Chiudi e salva le modifiche?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Memorizzazione dei cambiamenti locali…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Cambiamenti dei materiali:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commit Modifiche"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commit Modifiche"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Corrispondenze:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Crea Nuovo Progetto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Rimuovi una traccia d'animazione"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Crea Nuovo Progetto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Rimuovi l'elemento"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Mesh Sorgente:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9961,30 +10142,23 @@ msgid "Typechange"
msgstr "Cambio di tipo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Stage selezionato"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Stage Tutto"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commit Modifiche"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Visualizza i file diffs prima di eseguire il commit nella versione più "
-"recente"
+#, fuzzy
+msgid "View:"
+msgstr "Vista"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Nessun file diff è attivo"
+#, fuzzy
+msgid "Split"
+msgstr "Dividi Percorso"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Individua cambiamenti nei file diff"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificato"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12693,6 +12867,7 @@ msgid "Export list to a CSV file"
msgstr "Esporta l'elenco in un file CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Percorso Risorsa"
@@ -13544,6 +13719,40 @@ msgstr "Aggiorna grafico"
msgid "Edit Member"
msgstr "Modifica membro"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Cambia espressione"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animazione"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Il tipo di input non è iterabile: "
@@ -13556,6 +13765,88 @@ msgstr "L'iteratore è diventato invalido"
msgid "Iterator became invalid: "
msgstr "L'iteratore è diventato invalido: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Rinomina cartella:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Inclinazione:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipo:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Proprio"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Al carattere %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Aggiungi %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Imposta %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Aggiungi %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Ottieni %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nome proprietà indice invalido."
@@ -13572,6 +13863,21 @@ msgstr "Il percorso non conduce a un Nodo!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nome proprietà indice invalido \"%s\" nel nodo %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Imposta %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funzioni"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ridimensiona lista"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argomento invalido di tipo: "
@@ -13581,6 +13887,10 @@ msgid ": Invalid arguments: "
msgstr ": Argomenti invalidi: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet non trovato nello script: "
@@ -13589,6 +13899,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet non trovato nello script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Ricarica"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Indice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Indice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Costante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Costante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Costante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Costante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Singleton GDNative abilitato"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nodo TimeScale"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Modifica delle scene"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Proprio"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Taglia nodi"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Il nodo personalizzato non ha alcun metodo _step(), impossibile elaborare il "
@@ -13602,13 +13972,75 @@ msgstr ""
"Valore di ritorno di _step() non valido, deve essere un intero (seq out), "
"oppure una stringa (errore)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Chiamate"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Costanti"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usa Spazio Locale"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usa Spazio Locale"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Azione"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Ricerca VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Ottieni %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Sposta Frame"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "% fotogramma fisico"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Segnale"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Segnale"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Istanza"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14281,15 +14713,25 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Le particelle basate su GPU non sono supportate dal driver video GLES2.\n"
"Utilizzare invece il nodo CPUParticles2D. A tale scopo è possibile "
"utilizzare l'opzione \"Converti in CPUParticles\"."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14546,10 +14988,11 @@ msgid "Only uniform scales are supported."
msgstr "Solo scale uniformi sono supportate."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Le particelle basate su GPU non sono supportate dal driver video GLES2.\n"
"Utilizzare invece il nodo CPUParticles. A tale scopo è possibile utilizzare "
@@ -14557,6 +15000,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "Nulla é visibile perché le mesh non sono state assegnate ai draw pass."
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 5ed1e5c5fe..1e6c425b50 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -390,6 +390,7 @@ msgstr "%d æ–°è¦ãƒˆãƒ©ãƒƒã‚¯ã‚’作æˆã—ã€ã‚­ãƒ¼ã‚’挿入ã—ã¾ã™ã‹ï¼Ÿ"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -860,6 +861,7 @@ msgstr "追加"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -909,8 +911,7 @@ msgstr "ã‚·ã‚°ãƒŠãƒ«ã«æŽ¥ç¶šã§ãã¾ã›ã‚“"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1974,7 +1975,6 @@ msgid "New Folder..."
msgstr "æ–°è¦ãƒ•ォルダー..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "å†èª­ã¿è¾¼ã¿"
@@ -2091,7 +2091,8 @@ msgstr "ディレクトリã¨ãƒ•ァイル:"
msgid "Preview:"
msgstr "プレビュー:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "ファイル:"
@@ -2266,7 +2267,7 @@ msgstr "メソッド"
msgid "Signal"
msgstr "シグナル"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "コンスタント"
@@ -2297,6 +2298,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "%s を設定"
@@ -3051,8 +3054,9 @@ msgid "Install Android Build Template..."
msgstr "Androidビルドテンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "プロジェクトã®ãƒ‡ãƒ¼ã‚¿ãƒ•ォルダーを開ã"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "エディターã®ãƒ‡ãƒ¼ã‚¿ãƒ•ォルダーを開ã"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3211,10 +3215,6 @@ msgid "Toggle Fullscreen"
msgstr "フルスクリーンを有効化 / 無効化"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "システムコンソールを有効化 / 無効化"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "エディターã®ãƒ‡ãƒ¼ã‚¿ / 設定フォルダーを開ã"
@@ -3445,6 +3445,7 @@ msgid "Load Errors"
msgstr "読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "é¸æŠž"
@@ -3521,7 +3522,6 @@ msgid "Author"
msgstr "作者"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "ステータス"
@@ -3763,6 +3763,12 @@ msgstr "シーンã®ãƒ‘ス:"
msgid "Import From Node:"
msgstr "ノードã‹ã‚‰ã‚¤ãƒ³ãƒãƒ¼ãƒˆ:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "エラー"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "ã“れらã®ãƒ†ãƒ³ãƒ—レートãŒã‚るフォルダーを開ãã¾ã™ã€‚"
@@ -4651,6 +4657,7 @@ msgid "Subfolder:"
msgstr "サブフォルダー:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "作者:"
@@ -6343,6 +6350,7 @@ msgid "Zoom to 1600%"
msgstr "1600%ã«ã‚ºãƒ¼ãƒ "
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "%s を追加"
@@ -9722,7 +9730,8 @@ msgid "TileSet"
msgstr "タイルセット"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "VCSアドオンã¯åˆ©ç”¨ã§ãã¾ã›ã‚“。"
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9730,16 +9739,56 @@ msgid "Error"
msgstr "エラー"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "ステージã«è¿½åŠ ã•れã¦ã„るファイルãŒã‚りã¾ã›ã‚“"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "åå‰ãŒä»˜ã„ã¦ã„ã¾ã›ã‚“。"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "コミット"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCSアドオンã¯åˆæœŸåŒ–ã•れã¦ã„ã¾ã›ã‚“"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "シェーダーã®å¤‰æ›´:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "シェーダーã®å¤‰æ›´:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "コミット"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "サブツリー"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "複数ã®ãƒ—ロジェクトを開ã„ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "リセット"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9750,16 +9799,148 @@ msgid "Initialize"
msgstr "åˆæœŸåŒ–"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "ステージングエリア"
+#, fuzzy
+msgid "Remote Login"
+msgstr "ãƒã‚¤ãƒ³ãƒˆã‚’削除"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "åå‰ã®å¤‰æ›´"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "æ–°ã—ã„変更点を検出"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "変更点"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "変更をä¿å­˜ã—ã¦é–‰ã˜ã¾ã™ã‹ï¼Ÿ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "ローカルã®å¤‰æ›´ã‚’ä¿å­˜..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "マテリアルã®å¤‰æ›´:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "変更をコミットã™ã‚‹"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "変更をコミットã™ã‚‹"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "コミット"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "一致:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "æ–°è¦ãƒ—ロジェクトを作æˆ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "アニメーショントラックを除去"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "リモート"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "æ–°è¦ãƒ—ロジェクトを作æˆ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "アイテムを除去"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "リモート "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "リモート "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "ソースメッシュ:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9778,28 +9959,23 @@ msgid "Typechange"
msgstr "タイプ変更"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚¹ãƒ†ãƒ¼ã‚¸ã™ã‚‹"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "ã™ã¹ã¦ã‚’ステージã™ã‚‹"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "変更をコミットã™ã‚‹"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "最新ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚³ãƒŸãƒƒãƒˆã™ã‚‹å‰ã«ãƒ•ァイルã®å·®åˆ†ã‚’表示"
+#, fuzzy
+msgid "View:"
+msgstr "ビュー"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "有効ãªãƒ•ァイル差分ã¯ã‚りã¾ã›ã‚“"
+#, fuzzy
+msgid "Split"
+msgstr "パスを分割"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "ファイル差分ã®å¤‰æ›´ã‚’検知"
+#, fuzzy
+msgid "Unified"
+msgstr "変更済ã¿"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12481,6 +12657,7 @@ msgid "Export list to a CSV file"
msgstr "リストをCSVファイルã«ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "リソース パス"
@@ -13330,6 +13507,40 @@ msgstr "グラフを更新"
msgid "Edit Member"
msgstr "メンãƒãƒ¼ã‚’編集"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "å¼ã‚’設定"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "アニメーション"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "入力タイプã¯å復å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“: "
@@ -13342,6 +13553,88 @@ msgstr "イテレーターãŒç„¡åйã«ãªã‚Šã¾ã—ãŸ"
msgid "Iterator became invalid: "
msgstr "イテレーターãŒç„¡åйã«ãªã‚Šã¾ã—ãŸ: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "フォルダーåを変更:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "ピッãƒ:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "åž‹:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "自己"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "文字 %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "%s を追加"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "%s を設定"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "%s を追加"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "%s ã‚’å–å¾—"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "インデックスã®ãƒ—ロパティåãŒç„¡åйã§ã™ã€‚"
@@ -13358,6 +13651,21 @@ msgstr "パスãŒãƒŽãƒ¼ãƒ‰ã«é”ã—ã¾ã›ã‚“ï¼"
msgid "Invalid index property name '%s' in node %s."
msgstr "ノード%sã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ãƒ—ロパティå'%s'ã¯ç„¡åйã§ã™ã€‚"
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "%s を設定"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "関数"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "é…列ã®ã‚µã‚¤ã‚ºã‚’変更"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ":無効ãªå¼•æ•° 引数ã®åž‹: "
@@ -13367,6 +13675,10 @@ msgid ": Invalid arguments: "
msgstr ": 無効ãªå¼•æ•°: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚りã¾ã›ã‚“: "
@@ -13375,6 +13687,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSetãŒã‚¹ã‚¯ãƒªãƒ—ト内ã«ã‚りã¾ã›ã‚“: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "å†èª­ã¿è¾¼ã¿"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Zインデックス"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Zインデックス"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "コンスタント"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "コンスタント"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "コンスタント"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "コンスタント"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "有効ãªGDNativeシングルトン"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "タイムシーク ノード"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "シーンツリーã®ç·¨é›†"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "自己"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "ノードを切りå–ã‚‹"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "カスタムノードã«_step() メソッドãŒç„¡ã„ãŸã‚ã€ã‚°ãƒ©ãƒ•を処ç†ã§ãã¾ã›ã‚“。"
@@ -13386,13 +13758,75 @@ msgstr ""
"_step()ã®æˆ»ã‚Šå€¤ãŒç„¡åйã§ã™ã€‚integer (seq out)ã¾ãŸã¯string (error)ã§ãªã‘れã°ãª"
"りã¾ã›ã‚“。"
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "呼ã³å‡ºã—"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "定数"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "ローカル空間を使用"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "ローカル空間を使用"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "アクション(Action)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "VisualScriptを検索"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "%s ã‚’å–å¾—"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "フレームã®ç§»å‹•"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "物ç†ãƒ•レーム %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "シグナル"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "シグナル"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "インスタンス"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14030,16 +14464,26 @@ msgstr ""
"ã®ã¿å‹•作ã—ã¾ã™ã€‚"
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒãƒ¼ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›"
"ん。\n"
"代ã‚りã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパー"
"ティクルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚"
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14294,10 +14738,11 @@ msgid "Only uniform scales are supported."
msgstr "uniform スケールã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚"
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒãƒ¼ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›"
"ん。\n"
@@ -14306,6 +14751,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "æç”»ãƒ‘スã«ãƒ¡ãƒƒã‚·ãƒ¥ãŒå‰²ã‚Šå½“ã¦ã‚‰ã‚Œã¦ã„ãªã„ãŸã‚ã€ä½•も表示ã•れã¾ã›ã‚“。"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 09eea3dce4..d436b3b6d1 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -387,6 +387,7 @@ msgstr "áƒáƒ®áƒáƒšáƒ˜ %d ჩáƒáƒœáƒáƒ¬áƒ”რების შექმნáƒ
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -869,6 +870,7 @@ msgstr "დáƒáƒ›áƒáƒ¢áƒ”ბáƒ"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -920,8 +922,7 @@ msgstr "დáƒáƒ›áƒáƒ™áƒáƒ•შირებელი სიგნáƒáƒšáƒ˜:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1989,7 +1990,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2109,7 +2109,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2286,7 +2287,7 @@ msgstr "მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ მხáƒáƒšáƒáƒ“"
msgid "Signal"
msgstr "სიგნáƒáƒšáƒ”ბი"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "მუდმივი"
@@ -2317,6 +2318,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3022,7 +3025,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "პრáƒáƒ”ქტის დáƒáƒ›áƒ¤áƒ£áƒ«áƒœáƒ”ბლები"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3159,10 +3162,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3381,6 +3380,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3460,7 +3460,6 @@ msgid "Author"
msgstr "áƒáƒ•ტáƒáƒ áƒ”ბი"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3689,6 +3688,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "სáƒáƒ áƒ™áƒ”"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4578,6 +4583,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6292,6 +6298,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9705,7 +9712,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9713,7 +9720,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9721,10 +9733,41 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "ცვლილებáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "ცვლილებáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "ზუმის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ–ე დáƒáƒ§áƒ”ნებáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9733,7 +9776,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9742,54 +9815,143 @@ msgid "Detect new changes"
msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "ცვლილებáƒ"
+msgid "Stage all changes"
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ"
+msgid "Commit Message"
+msgstr "ცვლილებáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "წáƒáƒ¨áƒšáƒ"
+msgid "Commit Changes"
+msgstr "ცვლილებáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
+msgid "Commit List"
msgstr "ცვლილებáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¡áƒ¨áƒ¢áƒáƒ‘ის ცვლილებáƒ"
+msgid "Branches"
+msgstr "დáƒáƒ›áƒ—ხვევები:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "ყველáƒáƒ¡ ჩáƒáƒœáƒáƒªáƒ•ლებáƒ"
+msgid "Create New Branch"
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
+msgid "Remove Branch"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ თრექის წáƒáƒ¨áƒšáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "მáƒáƒ¨áƒáƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "áƒáƒ£áƒ“ირგáƒáƒ“áƒáƒ›áƒ¢áƒáƒœáƒ˜áƒ¡ სáƒáƒ®áƒ”ლის ცვლილებáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "წáƒáƒ¨áƒšáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
msgstr "ცვლილებáƒ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "View:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "Split"
+msgstr "კვáƒáƒœáƒ«áƒ˜áƒ¡ მრუდის რედáƒáƒ¥áƒ¢áƒ˜áƒ áƒ”ბáƒ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12368,6 +12530,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13222,6 +13385,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "ფუნქციები:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13234,6 +13430,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13250,6 +13520,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "ფუნქციები:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "მáƒáƒ¡áƒ˜áƒ•ის ზáƒáƒ›áƒ˜áƒ¡ ცვლილებáƒ"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13259,6 +13543,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13267,6 +13555,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "მუდმივი"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "მუდმივი"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "მუდმივი"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "მუდმივი"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "წáƒáƒ¨áƒšáƒ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "შექმნáƒ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ გáƒáƒ¡áƒáƒ¦áƒ”ბების áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13276,12 +13619,68 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "მუდმივი"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ყველრმáƒáƒœáƒ˜áƒ¨áƒœáƒ•áƒ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "სიგნáƒáƒšáƒ”ბი"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "სიგნáƒáƒšáƒ”ბი"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13855,7 +14254,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14068,7 +14476,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/km.po b/editor/translations/km.po
index 570aace246..db013eeb5d 100644
--- a/editor/translations/km.po
+++ b/editor/translations/km.po
@@ -357,6 +357,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -806,6 +807,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -855,8 +857,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1879,7 +1880,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1996,7 +1996,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2164,7 +2165,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2194,6 +2195,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2887,7 +2890,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3022,10 +3025,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3243,6 +3242,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3319,7 +3319,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3544,6 +3543,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4399,6 +4403,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6047,6 +6052,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9331,7 +9337,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9339,7 +9345,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9347,7 +9358,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9359,39 +9398,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9399,15 +9454,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11916,6 +12063,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12744,6 +12892,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12756,6 +12936,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12772,6 +13026,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12781,6 +13047,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12789,6 +13059,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "បញ្ចូល Key នៅទីនáŸáŸ‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12798,12 +13117,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13365,7 +13736,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13578,7 +13958,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 674d0ab18c..d35224bd42 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -385,6 +385,7 @@ msgstr "%dê°œì˜ ìƒˆ íŠ¸ëž™ì„ ë§Œë“¤ê³  키를 삽입할까요?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -852,6 +853,7 @@ msgstr "추가"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -903,8 +905,7 @@ msgstr "시그ë„ì„ ì—°ê²°í•  수 ì—†ìŒ"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1960,7 +1961,6 @@ msgid "New Folder..."
msgstr "새 í´ë”..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "새로고침"
@@ -2077,7 +2077,8 @@ msgstr "디렉토리 & 파ì¼:"
msgid "Preview:"
msgstr "미리보기:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "파ì¼:"
@@ -2253,7 +2254,7 @@ msgstr "메서드"
msgid "Signal"
msgstr "시그ë„"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "ìƒìˆ˜"
@@ -2284,6 +2285,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Set %s"
@@ -3035,8 +3038,9 @@ msgid "Install Android Build Template..."
msgstr "Android 빌드 템플릿 설치..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "프로ì íЏ ë°ì´í„° í´ë” 열기"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "ì—디터 ë°ì´í„° í´ë” 열기"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3192,10 +3196,6 @@ msgid "Toggle Fullscreen"
msgstr "전체 화면 토글"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "시스템 콘솔 토글"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "ì—디터 ë°ì´í„°/설정 í´ë” 열기"
@@ -3423,6 +3423,7 @@ msgid "Load Errors"
msgstr "불러오기 오류"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "ì„ íƒ"
@@ -3499,7 +3500,6 @@ msgid "Author"
msgstr "ì €ìž"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "ìƒíƒœ"
@@ -3739,6 +3739,12 @@ msgstr "씬 경로:"
msgid "Import From Node:"
msgstr "노드ì—서 가져오기:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "오류"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "ì´ í…œí”Œë¦¿ì„ í¬í•¨í•˜ëŠ” í´ë”를 엽니다."
@@ -4622,6 +4628,7 @@ msgid "Subfolder:"
msgstr "하위 í´ë”:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "ì €ìž:"
@@ -6306,6 +6313,7 @@ msgid "Zoom to 1600%"
msgstr "1600%로 줌"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "%s 추가"
@@ -9670,7 +9678,8 @@ msgid "TileSet"
msgstr "타ì¼ì…‹"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "ì´ìš©í•  수 있는 버전 관리 시스템(VCS)ì´ ì—†ìŠµë‹ˆë‹¤."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9678,16 +9687,56 @@ msgid "Error"
msgstr "오류"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "스테ì´ì§€ì— ì¶”ê°€ëœ íŒŒì¼ì´ 없습니다"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "ì´ë¦„ì„ ì œê³µí•˜ì§€ 않았습니다."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "커밋"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "버전 관리 시스템(VCS)ì´ ì´ˆê¸°í™”ë˜ì§€ 않았습니다"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "ì…°ì´ë” 바꾸기:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "ì…°ì´ë” 바꾸기:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "커밋"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "하위 트리"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "ë‘ ê°œ ì´ìƒì˜ 프로ì íŠ¸ë¥¼ 여시겠습니까?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "재설정 ì ìš©"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9698,16 +9747,148 @@ msgid "Initialize"
msgstr "초기화"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "스테ì´ì§• ì˜ì—­"
+#, fuzzy
+msgid "Remote Login"
+msgstr "ì  ì œê±°"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "ì´ë¦„ 바꾸기"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "새 변경사항 ê°ì§€"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "변경사항"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "ë³€ê²½ì‚¬í•­ì„ ì €ìž¥í•˜ê³  ë‹«ì„까요?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "로컬 ë³€ê²½ì‚¬í•­ì„ ì €ìž¥í•˜ëŠ” 중..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "머티리얼 바꾸기:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "커밋 변경사항"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "커밋 변경사항"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "커밋"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "ì¼ì¹˜í•¨:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "새 프로ì íЏ 만들기"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "애니메ì´ì…˜ 트랙 제거"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "ì›ê²©"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "새 프로ì íЏ 만들기"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "항목 제거"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "ì›ê²© "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "ì›ê²© "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "ì›ë³¸ 메시:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9726,28 +9907,23 @@ msgid "Typechange"
msgstr "타입체ì¸ì§€"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "ì„ íƒ í•­ëª© 스테ì´ì§€ë¡œ 보내기"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "ëª¨ë‘ ìŠ¤í…Œì´ì§€ë¡œ 보내기"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "커밋 변경사항"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "최신 버전으로 커밋하기 ì „ì— íŒŒì¼ diff 보기"
+#, fuzzy
+msgid "View:"
+msgstr "보기"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "íŒŒì¼ diffê°€ 켜져 있지 않습니다"
+#, fuzzy
+msgid "Split"
+msgstr "경로 가르기"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "íŒŒì¼ ì°¨ì´ì—서 ê°ì§€í•œ 변경사항"
+#, fuzzy
+msgid "Unified"
+msgstr "수정ë¨"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12401,6 +12577,7 @@ msgid "Export list to a CSV file"
msgstr "목ë¡ì„ CSV 파ì¼ë¡œ 내보내기"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "리소스 경로"
@@ -13243,6 +13420,40 @@ msgstr "그래프 새로고침"
msgid "Edit Member"
msgstr "멤버 편집"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "í‘œí˜„ì‹ ì„¤ì •"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "애니메ì´ì…˜"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "반복할 수 없는 입력 타입: "
@@ -13255,6 +13466,88 @@ msgstr "Iteratorê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤"
msgid "Iterator became invalid: "
msgstr "Iteratorê°€ 잘못ë¨: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "í´ë” ì´ë¦„ 바꾸기:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Pitch:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "타입:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "ìžì²´"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "(ë¬¸ìž %s 위치)"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "%s 추가"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Set %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "%s 추가"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Get %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "ìž˜ëª»ëœ ì¸ë±ìФ ì†ì„± ì´ë¦„."
@@ -13271,6 +13564,21 @@ msgstr "노드를 지정하는 경로가 아닙니다!"
msgid "Invalid index property name '%s' in node %s."
msgstr "노드 %s ì•ˆì— ì¸ë±ìФ ì†ì„± ì´ë¦„ '%s'ì´(ê°€) 잘못ë˜ì—ˆìŠµë‹ˆë‹¤."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Set %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "함수(Function)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "ë°°ì—´ í¬ê¸° 바꾸기"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": ìž˜ëª»ëœ ì¸ìˆ˜ 타입: "
@@ -13280,6 +13588,10 @@ msgid ": Invalid arguments: "
msgstr ": ìž˜ëª»ëœ ì¸ìˆ˜: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGetì„ ìŠ¤í¬ë¦½íЏì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: "
@@ -13288,6 +13600,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSetì„ ìŠ¤í¬ë¦½íЏì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "새로고침"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z ì¸ë±ìФ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z ì¸ë±ìФ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "ìƒìˆ˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "ìƒìˆ˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "ìƒìˆ˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "ìƒìˆ˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "í™œì„±í™”ëœ GDNative 싱글톤"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "시간 íƒìƒ‰ 노드"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "씬 트리 편집"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "ìžì²´"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "노드 잘ë¼ë‚´ê¸°"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "커스텀 ë…¸ë“œì— _step() 메서드가 없습니다. 그래프를 처리할 수 없습니다."
@@ -13299,13 +13671,75 @@ msgstr ""
"_step()ì—서 ìž˜ëª»ëœ ë°˜í™˜ 값입니다. 정수 (seq out), ë˜ëŠ” 문ìžì—´ (error)ì´ì–´ì•¼ "
"합니다."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "호출"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ìƒìˆ˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "로컬 공간 사용"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "로컬 공간 사용"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ì•¡ì…˜"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "비주얼스í¬ë¦½íЏ 검색"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "프레임 ì´ë™"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "물리 프레임 %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "시그ë„"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "시그ë„"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "ì¸ìŠ¤í„´ìŠ¤í•˜ê¸°"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13922,15 +14356,25 @@ msgstr ""
"ParallaxLayer는 ParallaxBackground ë…¸ë“œì˜ ìžì‹ 노드로 ìžˆì„ ë•Œë§Œ ìž‘ë™í•©ë‹ˆë‹¤."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU 기반 파티í´ì€ GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n"
"대신 CPUParticles2D 노드를 사용하세요. ì´ ê²½ìš° \"CPUParticles로 변환\" 옵션"
"ì„ ì‚¬ìš©í•  수 있습니다."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14177,10 +14621,11 @@ msgid "Only uniform scales are supported."
msgstr "Uniform 스케ì¼ë§Œ ì§€ì›ë©ë‹ˆë‹¤."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPU 기반 파티í´ì€ GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n"
"대신 CPUParticles 노드를 사용하세요. ì´ ê²½ìš° \"CPUParticles로 변환\" ì„¤ì •ì„ "
@@ -14188,6 +14633,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "메시가 패스를 그리ë„ë¡ ì§€ì •í•˜ì§€ 않아서, 아무 ê²ƒë„ ë³´ì´ì§€ 않습니다."
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index c9ef760bbf..53f33e0585 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -370,6 +370,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -842,6 +843,7 @@ msgstr "PridÄ—ti"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -892,8 +894,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1947,7 +1948,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2066,7 +2066,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2241,7 +2242,7 @@ msgstr ""
msgid "Signal"
msgstr "Signalai"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstanta"
@@ -2272,6 +2273,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2980,8 +2983,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr ""
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Atidaryti"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3117,10 +3121,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3340,6 +3340,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3421,7 +3422,6 @@ msgid "Author"
msgstr "Autorius:"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3655,6 +3655,12 @@ msgstr "Kelias iki Scenos:"
msgid "Import From Node:"
msgstr "Importuoti iš Nodo:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Įvyko klaida kraunant šriftą."
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4554,6 +4560,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autorius:"
@@ -6267,6 +6274,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9693,7 +9701,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9701,7 +9709,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9710,10 +9723,40 @@ msgid "Commit"
msgstr "BendruomenÄ—"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "BendruomenÄ—"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Atstatyti PriartinimÄ…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9722,7 +9765,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Panaikinti pasirinkimÄ…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Naujas pavadinimas:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9731,50 +9804,139 @@ msgid "Detect new changes"
msgstr "Sukurti NaujÄ…"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Sukurti NaujÄ…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Naujas pavadinimas:"
+msgid "Commit Message"
+msgstr "BendruomenÄ—"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Ištrinti Efektą"
+msgid "Commit List"
+msgstr "BendruomenÄ—"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
+msgid "Create New Branch"
+msgstr "Sukurti NaujÄ…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Animacija: panaikinti įrašą"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Panaikinti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Sukurti NaujÄ…"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
msgstr "Panaikinti pasirinkimÄ…"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Remote Name"
+msgstr "Panaikinti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Panaikinti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Naujas pavadinimas:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Ištrinti Efektą"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12347,6 +12509,7 @@ msgid "Export list to a CSV file"
msgstr "Importuoti iš Nodo:"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13205,6 +13368,39 @@ msgstr ""
msgid "Edit Member"
msgstr "Redaguoti Filtrus"
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animacija"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13217,6 +13413,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13233,6 +13503,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "(Esama)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13242,6 +13525,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13250,6 +13537,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek Nodas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Sukurti"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Transition Nodas"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13259,12 +13601,70 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Animacija"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mix Nodas"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fizikos Kadro %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signalai"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signalai"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13840,7 +14240,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14053,7 +14462,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 4bd1bae67d..4d888fb41d 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -8,13 +8,13 @@
# Anonymous <noreply@weblate.org>, 2020.
# StiLins <aigars.skilins@gmail.com>, 2020.
# Rihards Kubilis <oldcar@inbox.lv>, 2020.
-# M E <gruffy7932@gmail.com>, 2021.
+# M E <gruffy7932@gmail.com>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-11-29 20:38+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: M E <gruffy7932@gmail.com>\n"
"Language-Team: Latvian <https://hosted.weblate.org/projects/godot-engine/"
"godot/lv/>\n"
@@ -24,7 +24,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= "
"19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n"
-"X-Generator: Weblate 4.10-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -365,6 +365,7 @@ msgstr "Izveidot %d JAUNU celiņu un ievietot atslēgievietni?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -832,6 +833,7 @@ msgstr "Pievienot"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -881,8 +883,7 @@ msgstr "Nevar savienot signÄlu"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1947,7 +1948,6 @@ msgid "New Folder..."
msgstr "Jauna mape..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "AtsvaidzinÄt"
@@ -2064,7 +2064,8 @@ msgstr "Mapes & Faili:"
msgid "Preview:"
msgstr "Priekškatījums:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fails:"
@@ -2239,7 +2240,7 @@ msgstr "Metode"
msgid "Signal"
msgstr "SignÄls"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstante"
@@ -2270,6 +2271,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Likt %s"
@@ -2317,7 +2320,7 @@ msgstr "Kopēt Izvēlēto"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "Notītīt"
+msgstr "Notīrīt"
#: editor/editor_log.cpp
msgid "Clear Output"
@@ -2990,8 +2993,9 @@ msgid "Install Android Build Template..."
msgstr "Instalēt Android būves šablonu..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Atvērt Projekta Datu Mapi"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Atvērt redaktora datu mapi"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3136,10 +3140,6 @@ msgid "Toggle Fullscreen"
msgstr "PÄrslÄ“gt PilnekrÄnu"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "PÄrslÄ“gt sistÄ“mas konsoli"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Atvērt redaktora datu / iestatījumu mapi"
@@ -3364,6 +3364,7 @@ msgid "Load Errors"
msgstr "IelÄdÄ“t kļūdas"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Izvēlēties"
@@ -3440,7 +3441,6 @@ msgid "Author"
msgstr "Autors"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Statuss"
@@ -3665,6 +3665,12 @@ msgstr "Ainas ceļš:"
msgid "Import From Node:"
msgstr "Importēt no mezgla:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Kļūda!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4376,7 +4382,7 @@ msgstr ""
#: editor/import_dock.cpp
msgid "Clear Default for '%s'"
-msgstr ""
+msgstr "Notīrtīt noklusējumu priekš '%s'"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4524,6 +4530,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autors:"
@@ -5800,7 +5807,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Bones"
-msgstr ""
+msgstr "Notīrīt kaulus"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
@@ -6109,7 +6116,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
-msgstr ""
+msgstr "Notīrīt pozu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add Node Here"
@@ -6172,6 +6179,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -7457,7 +7465,7 @@ msgstr "Meklēšanas RezultÄti"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Scripts"
-msgstr ""
+msgstr "Notīrīt nesenos skriptus"
#: editor/plugins/script_text_editor.cpp
msgid "Connections to method:"
@@ -8460,7 +8468,7 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select/Clear All Frames"
-msgstr ""
+msgstr "Izvēlēties/notīrīt visus kadrus"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Create Frames from Sprite Sheet"
@@ -9462,7 +9470,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9470,7 +9478,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9478,8 +9491,42 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Ä’notÄja izmaiņas:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Ä’notÄja izmaiņas:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komūns"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
msgstr ""
+"Vai esat droÅ¡s(Å¡a), ka vÄ“laties noņemt visus savienojumus no šī signÄla?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Pielietot atiestatīšanu"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9490,7 +9537,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Noņemt Punktu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "PÄrsaukt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9498,8 +9575,109 @@ msgid "Detect new changes"
msgstr "Atrast jaunas izmaiņas"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Maiņas"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "AizvÄ“rt un saglabÄt izmaiņas?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "SaglabÄ lokÄlÄs izmaiņas..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "SaglabÄ lokÄlÄs izmaiņas..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Pielietot izmaiņas"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Pielietot izmaiņas"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Pielietot izmaiņas"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Sakritības:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Izveidot Jaunu %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Noņemt Anim. Celiņu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Noņemt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Izveidot Jaunu %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Noņemt vienumu"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Mezgla VÄrds:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Noņemt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9518,27 +9696,20 @@ msgid "Typechange"
msgstr "Tipa maiņa"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Posma izvēle"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Pielietot izmaiņas"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
+#, fuzzy
+msgid "View:"
+msgstr "Skatīt"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12051,6 +12222,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12879,6 +13051,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animÄcija"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12891,6 +13096,83 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Sevi"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Pie rakstzīmes %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Likt %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12907,6 +13189,21 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Likt %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcijas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Mainīt Masīva Lielumu"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12916,6 +13213,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12924,6 +13225,63 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "PÄrlÄdÄ“t"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Izdzēst Mezglu"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Ainas koka rediģēšana"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Sevi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Izgriezt mezglu(s)"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12933,14 +13291,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Izsaukumi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Darbība"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "NÄkamÄ cilne"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fizikas kadrs %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "SignÄls"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "SignÄls"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Å ablons"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13500,7 +13918,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13713,7 +14140,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 535251ede2..52b6fecb05 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -349,6 +349,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -798,6 +799,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -847,8 +849,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1871,7 +1872,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1988,7 +1988,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2156,7 +2157,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2186,6 +2187,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2879,7 +2882,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3014,10 +3017,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3234,6 +3233,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3310,7 +3310,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3535,6 +3534,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4390,6 +4394,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6033,6 +6038,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9315,7 +9321,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9323,7 +9329,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9331,7 +9342,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9343,39 +9382,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9383,15 +9438,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11900,6 +12047,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12728,6 +12876,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12740,6 +12920,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12756,6 +13010,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12765,6 +13031,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12773,6 +13043,54 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12782,12 +13100,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13349,7 +13719,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13562,7 +13941,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/mk.po b/editor/translations/mk.po
index e1a6d054c8..8448673f6c 100644
--- a/editor/translations/mk.po
+++ b/editor/translations/mk.po
@@ -357,6 +357,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -806,6 +807,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -855,8 +857,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1880,7 +1881,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1997,7 +1997,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2165,7 +2166,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2891,7 +2894,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3026,10 +3029,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3247,6 +3246,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3323,7 +3323,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3548,6 +3547,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4406,6 +4410,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6054,6 +6059,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9338,7 +9344,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9346,7 +9352,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9354,7 +9365,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9366,39 +9405,56 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Избриши невалидни клучеви"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "Select SSH private key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9406,15 +9462,108 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Избриши невалидни клучеви"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11923,6 +12072,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12751,6 +12901,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12763,6 +12945,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12779,6 +13035,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12788,6 +13056,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12796,6 +13068,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "ВнеÑи клуч тука"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12805,12 +13126,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13372,7 +13745,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13585,7 +13967,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 50770a8962..b6e14ce0cb 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -359,6 +359,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -810,6 +811,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -859,8 +861,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1884,7 +1885,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2001,7 +2001,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2170,7 +2171,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2202,6 +2203,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2898,7 +2901,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3033,10 +3036,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3254,6 +3253,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3330,7 +3330,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3555,6 +3554,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4411,6 +4415,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6063,6 +6068,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9348,7 +9354,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9356,7 +9362,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9364,7 +9375,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9376,39 +9415,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9416,15 +9471,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11933,6 +12080,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12763,6 +12911,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "ചലനം à´šàµà´±àµà´±àµ½"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12775,6 +12956,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12791,6 +13046,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•ൾ:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12800,6 +13068,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12808,6 +13080,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "സൂചിക ഇവിടെയിടàµà´•"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12817,12 +13138,65 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "à´ªàµà´°à´µàµƒà´¤àµà´¤à´¿à´•ൾ:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13384,7 +13758,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13597,7 +13980,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index 6a5005167a..4e1324414e 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -356,6 +356,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -806,6 +807,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -855,8 +857,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1879,7 +1880,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1996,7 +1996,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2164,7 +2165,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3244,6 +3243,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3320,7 +3320,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3545,6 +3544,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "तà¥à¤°à¥à¤Ÿà¥€!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4400,6 +4405,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6047,6 +6053,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9333,7 +9340,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9341,7 +9348,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9349,7 +9361,36 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "समà¥à¤¦à¤¾à¤¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9361,39 +9402,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9401,15 +9458,111 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Commit List"
+msgstr "समà¥à¤¦à¤¾à¤¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "10"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "नवीन अâ€à¥…निमेशन तयार करा"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "नवीन नोड तयार करा."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "नोड काढला"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11920,6 +12073,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12749,6 +12903,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "अâ€à¥…निमेशन टà¥à¤°à¥€"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12761,6 +12948,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12777,6 +13038,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12786,6 +13059,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12794,6 +13071,55 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "नोड हलवा"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12803,12 +13129,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13370,7 +13748,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13583,7 +13970,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index 4909f7f9b1..7fc1062ff2 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -8,16 +8,16 @@
# 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, 2021.
+# Keviindran Ramachandran <keviinx@yahoo.com>, 2020, 2021, 2022.
# Jacque Fresco <aidter@use.startmail.com>, 2021.
-# Lemoney <railkill@gmail.com>, 2021.
+# Lemoney <railkill@gmail.com>, 2021, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-10-10 10:18+0000\n"
-"Last-Translator: Lemoney <railkill@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+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"
@@ -25,7 +25,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.9-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -328,7 +328,7 @@ msgstr "Menduakan Kunci"
#: editor/animation_track_editor.cpp
msgid "Add RESET Value(s)"
-msgstr ""
+msgstr "Tambah Nilai-nilai RESET"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -365,6 +365,7 @@ msgstr "Cipta %d BARU trek dan masukkan kunci?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -499,9 +500,8 @@ msgstr ""
"trek."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "Kunci Skala Anim"
+msgstr "Anim Tambah Kekunci RESET"
#: editor/animation_track_editor.cpp
msgid ""
@@ -832,6 +832,7 @@ msgstr "Tambah"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -883,8 +884,7 @@ msgstr "Tidak dapat menyambungkan isyarat"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1489,7 +1489,7 @@ msgstr "Nama tidak sah."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Tidak boleh bermula dengan digit."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1857,9 +1857,8 @@ msgid "Error saving profile to path: '%s'."
msgstr "Ralat menyimpan profil ke laluan: '%s'."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Reset to Default"
-msgstr "Set Semula ke Lalai"
+msgstr "Pulih ke Keadaan Asal"
#: editor/editor_feature_profile.cpp
msgid "Current Profile:"
@@ -1954,7 +1953,6 @@ msgid "New Folder..."
msgstr "Folder Baru..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Muat Semula"
@@ -2071,7 +2069,8 @@ msgstr "Direktori & Fail:"
msgid "Preview:"
msgstr "Pratonton:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fail:"
@@ -2121,9 +2120,8 @@ msgid "Properties"
msgstr "Sifat-sifat"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "ganti:"
+msgstr "ganti %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2139,7 +2137,7 @@ msgstr "Sifat Tema"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Colors"
-msgstr ""
+msgstr "Warna"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constants"
@@ -2147,15 +2145,15 @@ msgstr "Pemalar"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Fonts"
-msgstr ""
+msgstr "Fon"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Icons"
-msgstr ""
+msgstr "Ikon"
#: editor/editor_help.cpp
msgid "Styles"
-msgstr ""
+msgstr "Gaya"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2246,7 +2244,7 @@ msgstr "Kaedah"
msgid "Signal"
msgstr "Isyarat"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Pemalar"
@@ -2263,20 +2261,22 @@ msgid "Property:"
msgstr "Sifat:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(nilai)"
+msgstr "Nilai pin"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"Menyemat nilai memaksanya untuk disimpan walaupun ia sama dengan nilai asal."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
-msgstr ""
+msgstr "Nilai pin [Dinyahdayakan kerana '%s' adalah editor sahaja]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Tetapkan %s"
@@ -2287,26 +2287,23 @@ msgstr "Tetapkan Pelbagai:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Dipinkan %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "%s tidak dipinkan"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Sifat-sifat"
+msgstr "Salin Sifat"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Sifat-sifat"
+msgstr "Tampal Sifat"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Sifat-sifat"
+msgstr "Salin Laluan Sifat"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2483,9 +2480,8 @@ msgstr ""
"warisan) tidak dapat dipenuhi."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Could not save one or more scenes!"
-msgstr "Tidak dapat memulakan subproses!"
+msgstr "Tidak dapat menyimpan satu atau lebih adegan!"
#: editor/editor_node.cpp
msgid "Save All Scenes"
@@ -2628,20 +2624,23 @@ msgstr "Simpan perubahan pada '%s' sebelum menutup?"
#: editor/editor_node.cpp
msgid "%s no longer exists! Please specify a new save location."
-msgstr ""
+msgstr "%s tidak lagi wujud! Sila nyatakan lokasi simpan baru."
#: editor/editor_node.cpp
msgid ""
"The current scene has no root node, but %d modified external resource(s) "
"were saved anyway."
msgstr ""
+"Adegan semasa tidak mempunyai nod akar, tetapi %d sumber luaran yang diubah "
+"suai telah disimpan juga."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"A root node is required to save the scene. You can add a root node using the "
"Scene tree dock."
-msgstr "Nod akar diperlukan untuk menyimpan adegan."
+msgstr ""
+"Nod akar diperlukan untuk menyimpan adegan. Anda boleh menambah nod akar "
+"menggunakan dok pokok Adegan."
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -2673,29 +2672,27 @@ msgstr "Adegan semasa tidak disimpan. Masih buka?"
#: editor/editor_node.cpp
msgid "Can't undo while mouse buttons are pressed."
-msgstr ""
+msgstr "Tidak boleh buat asal semasa butang tetikus ditekan."
#: editor/editor_node.cpp
msgid "Nothing to undo."
-msgstr ""
+msgstr "Tiada apa yang perlu dibuat asal."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo: %s"
-msgstr "Buat Asal"
+msgstr "Buat asal: %s"
#: editor/editor_node.cpp
msgid "Can't redo while mouse buttons are pressed."
-msgstr ""
+msgstr "Tidak boleh buat semula semasa butang tetikus ditekan."
#: editor/editor_node.cpp
msgid "Nothing to redo."
-msgstr ""
+msgstr "Tiada apa yang perlu dibuat semula."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Redo: %s"
-msgstr "Buat Semula"
+msgstr "Buat semula: %s"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
@@ -3035,8 +3032,9 @@ msgid "Install Android Build Template..."
msgstr "Pasang Templat Binaan Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Buka Folder Data Projek"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Buka Folder Data Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3126,7 +3124,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "Paksa Shader Fallbacks"
#: editor/editor_node.cpp
msgid ""
@@ -3137,6 +3135,13 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"Apabila pilihan ini didayakan, shader akan digunakan dalam bentuk fallback "
+"mereka (sama ada boleh dilihat melalui ubershader atau tersembunyi) "
+"sepanjang masa berjalan.\n"
+"Ini berguna untuk mengesahkan rup dan prestasi fallback, yang biasanya "
+"diaparkan secara ringkas.\n"
+"Kompilasi shader tak segerak mesti didayakan dalam tetapan projek untuk "
+"pilihan ini membuat perubahan."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3195,10 +3200,6 @@ msgid "Toggle Fullscreen"
msgstr "Togol Skrin Penuh"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Togol Konsol Sistem"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Buka Folder Data/Tetapan Editor"
@@ -3223,13 +3224,12 @@ msgid "Help"
msgstr "Bantuan"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Online Documentation"
-msgstr "Dokumen Dalam Talian"
+msgstr "Dokumentasi Dalam Talian"
#: editor/editor_node.cpp
msgid "Questions & Answers"
-msgstr ""
+msgstr "Soalan & Jawapan"
#: editor/editor_node.cpp
msgid "Report a Bug"
@@ -3237,7 +3237,7 @@ msgstr "Laporkan Pepijat"
#: editor/editor_node.cpp
msgid "Suggest a Feature"
-msgstr ""
+msgstr "Cadangkan Ciri"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
@@ -3248,9 +3248,8 @@ msgid "Community"
msgstr "Komuniti"
#: editor/editor_node.cpp
-#, fuzzy
msgid "About Godot"
-msgstr "Tentang"
+msgstr "Tentang Godot"
#: editor/editor_node.cpp
msgid "Support Godot Development"
@@ -3342,13 +3341,12 @@ msgid "Manage Templates"
msgstr "Urus Templat-templat"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Install from file"
-msgstr "Pasang Dari Fail"
+msgstr "Pasang dari fail"
#: editor/editor_node.cpp
msgid "Select android sources file"
-msgstr ""
+msgstr "Pilih fail sumber android"
#: editor/editor_node.cpp
msgid ""
@@ -3398,9 +3396,8 @@ msgid "Merge With Existing"
msgstr "Gabung Dengan Sedia Ada"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Apply MeshInstance Transforms"
-msgstr "Anim Ubah Perubahan"
+msgstr "Gunakan MeshInstance Transforms"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
@@ -3433,13 +3430,13 @@ msgid "Load Errors"
msgstr "Muatkan Ralat-ralat"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Pilih"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Select Current"
-msgstr "Pilih Folder Semasa"
+msgstr "Pilih Semasa"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
@@ -3474,9 +3471,8 @@ msgid "No sub-resources found."
msgstr "Tiada sub-sumber dijumpai."
#: editor/editor_path.cpp
-#, fuzzy
msgid "Open a list of sub-resources."
-msgstr "Tiada sub-sumber dijumpai."
+msgstr "Buka senarai sub-sumber."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
@@ -3507,29 +3503,25 @@ msgid "Version"
msgstr "Versi"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Author"
msgstr "Pengarang"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
-msgstr ""
+msgstr "Status"
#: editor/editor_profiler.cpp
msgid "Measure:"
msgstr "Ukur:"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Frame Time (ms)"
-msgstr "Masa Bingkai (saat)"
+msgstr "Masa Bingkai (ms)"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Average Time (ms)"
-msgstr "Masa Purata (saat)"
+msgstr "Masa Purata (ms)"
#: editor/editor_profiler.cpp
msgid "Frame %"
@@ -3556,6 +3548,13 @@ msgid ""
"functions called by that function.\n"
"Use this to find individual functions to optimize."
msgstr ""
+"Inklusif: Termasuk masa daripada fungsi lain yang dipanggil oleh fungsi "
+"ini.\n"
+"Gunakan ini untuk mengesan kesesakan.\n"
+"\n"
+"Diri: Hanya kira masa yang dihabiskan dalam fungsi itu sendiri, bukan dalam "
+"fungsi lain yang dipanggil oleh fungsi itu.\n"
+"Gunakan ini untuk mencari fungsi individu untuk dioptimumkan."
#: editor/editor_profiler.cpp
msgid "Frame #:"
@@ -3661,7 +3660,7 @@ msgstr ""
#: editor/editor_resource_picker.cpp
msgid "Quick Load"
-msgstr ""
+msgstr "Muatan Cepat"
#: editor/editor_resource_picker.cpp editor/property_editor.cpp
msgid "Make Unique"
@@ -3682,9 +3681,8 @@ msgid "Paste"
msgstr "Tampal"
#: editor/editor_resource_picker.cpp editor/property_editor.cpp
-#, fuzzy
msgid "Convert to %s"
-msgstr "Tukar Kepada %s"
+msgstr "Tukar ke %s"
#: editor/editor_resource_picker.cpp editor/property_editor.cpp
msgid "New %s"
@@ -3733,10 +3731,9 @@ msgid "Did you forget the '_run' method?"
msgstr "Adakah anda lupa kaedah '_run'?"
#: editor/editor_spin_slider.cpp
-#, fuzzy
msgid "Hold %s to round to integers. Hold Shift for more precise changes."
msgstr ""
-"Tahan Ctrl untuk bundarkan ke integer. Tahan Shift untuk perubahan yang "
+"Tahan %s untuk membundarkan ke integer. Tahan Shift untuk perubahan yang "
"lebih tepat."
#: editor/editor_sub_scene.cpp
@@ -3755,67 +3752,68 @@ msgstr "Laluan Adegan:"
msgid "Import From Node:"
msgstr "Import Dari Nod:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Ralat!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
-msgstr ""
+msgstr "Buka folder yang mengandungi templat ini."
#: editor/export_template_manager.cpp
msgid "Uninstall these templates."
-msgstr ""
+msgstr "Nyahpasang templat ini."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "There are no mirrors available."
-msgstr "Tiada fail '%s'."
+msgstr "Tiada mirror tersedia."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Retrieving the mirror list..."
-msgstr "Mengambil maklumat cermin, sila tunggu..."
+msgstr "Mendapatkan semula senarai mirror..."
#: editor/export_template_manager.cpp
msgid "Starting the download..."
-msgstr ""
+msgstr "Memulakan muat turun..."
#: editor/export_template_manager.cpp
msgid "Error requesting URL:"
msgstr "Ralat semasa meminta URL:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Connecting to the mirror..."
-msgstr "Menyambung ke Cermin..."
+msgstr "Menyambung ke mirror..."
#: editor/export_template_manager.cpp
msgid "Can't resolve the requested address."
-msgstr ""
+msgstr "Tidak dapat menyelesaikan alamat yang diminta."
#: editor/export_template_manager.cpp
msgid "Can't connect to the mirror."
msgstr "Tidak dapat menyambung ke tapak web."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "No response from the mirror."
-msgstr "Tiada jawapan."
+msgstr "Tiada jawapan dari mirror."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed."
-msgstr ""
+msgstr "Permintaan gagal."
#: editor/export_template_manager.cpp
msgid "Request ended up in a redirect loop."
-msgstr ""
+msgstr "Permintaan berakhir dalam loop pengalihan."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Request failed:"
-msgstr "Permintaan Gagal."
+msgstr "Permintaan gagal:"
#: editor/export_template_manager.cpp
msgid "Download complete; extracting templates..."
-msgstr ""
+msgstr "Muat turun selesai; mengekstrak templat..."
#: editor/export_template_manager.cpp
msgid "Cannot remove temporary file:"
@@ -3834,13 +3832,12 @@ msgid "Error getting the list of mirrors."
msgstr "Ralat mendapatkan senarai cermin-cermin."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error parsing JSON with the list of mirrors. Please report this issue!"
-msgstr "Ralat menghuraikan JSON senarai cermin. Sila laporkan isu ini!"
+msgstr "Ralat menghuraikan JSON dengan senarai mirror. Sila laporkan isu ini!"
#: editor/export_template_manager.cpp
msgid "Best available mirror"
-msgstr ""
+msgstr "Mirror terbaik yang tersedia"
#: editor/export_template_manager.cpp
msgid ""
@@ -3893,24 +3890,20 @@ msgid "SSL Handshake Error"
msgstr "Ralat Jabat Tangan SSL"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Can't open the export templates file."
-msgstr "Tidak dapat membuka zip templat eksport."
+msgstr "Tidak dapat membuka fail templat eksport."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Invalid version.txt format inside the export templates file: %s."
-msgstr "Format version.txt tidak sah di dalam templat: %s."
+msgstr "Format version.txt tidak sah di dalam fail templat eksport: %s."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "No version.txt found inside the export templates file."
-msgstr "Tiada version.txt dijumpai di dalam templat."
+msgstr "Tiada version.txt dijumpai di dalam fail templat eksport."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error creating path for extracting templates:"
-msgstr "Ralat mencipta laluan untuk templat-templat:"
+msgstr "Ralat mencipta laluan untuk mengekstrak templat:"
#: editor/export_template_manager.cpp
msgid "Extracting Export Templates"
@@ -3921,9 +3914,8 @@ msgid "Importing:"
msgstr "Mengimport:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Remove templates for the version '%s'?"
-msgstr "Alih keluar versi templat '%s'?"
+msgstr "Alih keluar templat versi '%s'?"
#: editor/export_template_manager.cpp
msgid "Uncompressing Android Build Sources"
@@ -3939,20 +3931,19 @@ msgstr "Versi Terkini:"
#: editor/export_template_manager.cpp
msgid "Export templates are missing. Download them or install from a file."
-msgstr ""
+msgstr "Templat eksport tiada. Muat turun atau pasang dari fail."
#: editor/export_template_manager.cpp
msgid "Export templates are installed and ready to be used."
-msgstr ""
+msgstr "Templat eksport dipasang dan sedia untuk digunakan."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Open Folder"
-msgstr "Buka Fail"
+msgstr "Buka Folder"
#: editor/export_template_manager.cpp
msgid "Open the folder containing installed templates for the current version."
-msgstr ""
+msgstr "Buka folder yang mengandungi templat yang dipasang untuk versi semasa."
#: editor/export_template_manager.cpp
msgid "Uninstall"
@@ -3960,45 +3951,41 @@ msgstr "Nyahpasang"
#: editor/export_template_manager.cpp
msgid "Uninstall templates for the current version."
-msgstr ""
+msgstr "Nyahpasang templat untuk versi semasa."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Download from:"
-msgstr "Muat turun"
+msgstr "Muat turun dari:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Open in Web Browser"
-msgstr "Buka dalam Pengurus Fail"
+msgstr "Buka dalam Pelayar Web"
#: editor/export_template_manager.cpp
msgid "Copy Mirror URL"
-msgstr ""
+msgstr "Salin URL Mirror"
#: editor/export_template_manager.cpp
msgid "Download and Install"
-msgstr ""
+msgstr "Muat Turun dan Pasang"
#: editor/export_template_manager.cpp
msgid ""
"Download and install templates for the current version from the best "
"possible mirror."
-msgstr ""
+msgstr "Muat turun dan pasang templat untuk versi semasa dari mirror terbaik."
#: editor/export_template_manager.cpp
msgid "Official export templates aren't available for development builds."
msgstr "Templat eksport rasmi tidak tersedia untuk binaan pembangunan."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Install from File"
-msgstr "Pasang Dari Fail"
+msgstr "Pasang dari Fail"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Install templates from a local file."
-msgstr "Import Templat Dari Fail ZIP"
+msgstr "Pasang templat dari fail tempatan."
#: editor/export_template_manager.cpp editor/find_in_files.cpp
#: editor/progress_dialog.cpp scene/gui/dialogs.cpp
@@ -4006,19 +3993,16 @@ msgid "Cancel"
msgstr "Batal"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Cancel the download of the templates."
-msgstr "Tidak dapat membuka zip templat eksport."
+msgstr "Batalkan muat turun templat."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Other Installed Versions:"
-msgstr "Versi-versi Yang Dipasang:"
+msgstr "Versi Terpasang Lain:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Uninstall Template"
-msgstr "Nyahpasang"
+msgstr "Nyahpasang Templat"
#: editor/export_template_manager.cpp
msgid "Select Template File"
@@ -4033,6 +4017,8 @@ msgid ""
"The templates will continue to download.\n"
"You may experience a short editor freeze when they finish."
msgstr ""
+"Templat akan terus dimuat turun.\n"
+"Anda mungkin mengalami pembekuan editor pendek apabila ia selesai."
#: editor/filesystem_dock.cpp
msgid "Favorites"
@@ -4180,33 +4166,32 @@ msgid "Collapse All"
msgstr "Runtuhkan Semua"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Sort files"
-msgstr "Cari fail"
+msgstr "Susun fail-fail"
#: editor/filesystem_dock.cpp
msgid "Sort by Name (Ascending)"
-msgstr ""
+msgstr "Susun mengikut Nama (Menaik)"
#: editor/filesystem_dock.cpp
msgid "Sort by Name (Descending)"
-msgstr ""
+msgstr "Susun mengikut Nama (Menurun)"
#: editor/filesystem_dock.cpp
msgid "Sort by Type (Ascending)"
-msgstr ""
+msgstr "Susun mengikut Jenis (Menaik)"
#: editor/filesystem_dock.cpp
msgid "Sort by Type (Descending)"
-msgstr ""
+msgstr "Susun mengikut Jenis (Menurun)"
#: editor/filesystem_dock.cpp
msgid "Sort by Last Modified"
-msgstr ""
+msgstr "Susun mengikut Terakhir Diubah Suai"
#: editor/filesystem_dock.cpp
msgid "Sort by First Modified"
-msgstr ""
+msgstr "Susun mengikut Pertama Diubah Suai"
#: editor/filesystem_dock.cpp
msgid "Duplicate..."
@@ -4218,7 +4203,7 @@ msgstr "Namakan semula..."
#: editor/filesystem_dock.cpp
msgid "Focus the search box"
-msgstr ""
+msgstr "Fokuskan kotak carian"
#: editor/filesystem_dock.cpp
msgid "Previous Folder/File"
@@ -4309,9 +4294,8 @@ msgid "Replace..."
msgstr "Ganti..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Ganti Semua"
+msgstr "Gantikan dalam Fail-fail"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4322,9 +4306,8 @@ msgid "Replace: "
msgstr "Ganti: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Ganti Semua"
+msgstr "Gantikan Semua (TIADA BUAT ASAL)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4517,6 +4500,10 @@ msgid ""
"Selecting another resource in the FileSystem dock without clicking Reimport "
"first will discard changes made in the Import dock."
msgstr ""
+"Anda mempunyai perubahan belum selesai yang belum digunakan lagi.Klik Import "
+"Semula untuk menggunakan perubahan yang dibuat pada pilihan import.\n"
+"Memilih sumber lain dalam dok FileSystem tampa mengklik Import Semula "
+"terlebih dahulu akan membuang perubahan yang dibuat dalam dok Import."
#: editor/import_dock.cpp
msgid "Import As:"
@@ -4546,20 +4533,20 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Pilih fail sumber dalam sistem fail atau dalam pemeriksa untuk melaraskan "
+"tetapan import."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
msgstr "Gagal untuk memuatkan sumber."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Copy Properties"
-msgstr "Sifat-sifat"
+msgstr "Salin Sifat-sifat"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Paste Properties"
-msgstr "Sifat-sifat"
+msgstr "Tampal Sifat-sifat"
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
@@ -4585,21 +4572,19 @@ msgstr "Simpan Sebagai..."
#: editor/inspector_dock.cpp
msgid "Extra resource options."
-msgstr ""
+msgstr "Pilihan sumber tambahan."
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Edit Resource from Clipboard"
-msgstr "Sunting Papan Klip Sumber"
+msgstr "Edit Sumber dari Papan Klip"
#: editor/inspector_dock.cpp
msgid "Copy Resource"
msgstr "Salin Sumber"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Make Resource Built-In"
-msgstr "Buat Terbina Dalaman"
+msgstr "Buat Sumber Terbina Dalam"
#: editor/inspector_dock.cpp
msgid "Go to the previous edited object in history."
@@ -4615,20 +4600,19 @@ msgstr "Sejarah objek-objek yang baru disunting."
#: editor/inspector_dock.cpp
msgid "Open documentation for this object."
-msgstr ""
+msgstr "Buka dokumentasi untuk objek ini."
#: editor/inspector_dock.cpp editor/scene_tree_dock.cpp
msgid "Open Documentation"
-msgstr ""
+msgstr "Buka Dokumentasi"
#: editor/inspector_dock.cpp
msgid "Filter properties"
msgstr "Tapis sifat-sifat"
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Manage object properties."
-msgstr "Sifat-sifat objek."
+msgstr "Urus sifat objek."
#: editor/inspector_dock.cpp
msgid "Changes may be lost!"
@@ -4659,6 +4643,7 @@ msgid "Subfolder:"
msgstr "Subfolder:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Pengarang:"
@@ -4843,7 +4828,6 @@ msgid "Remove BlendSpace2D Triangle"
msgstr "Keluarkan Segi tiga BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "BlendSpace2D does not belong to an AnimationTree node."
msgstr "BlendSpace2D bukan milik nod AnimationTree."
@@ -4874,9 +4858,8 @@ msgid "Blend:"
msgstr "Adun:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Parameter Changed:"
-msgstr "Parameter Berubah"
+msgstr "Parameter Berubah:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4885,29 +4868,31 @@ msgstr "Sunting Filters"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
-msgstr ""
+msgstr "Nod keluaran tidak boleh ditambah ke pokok adunan."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Add Node to BlendTree"
-msgstr ""
+msgstr "Tambah Nod ke BlendTree"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Node Moved"
-msgstr ""
+msgstr "Nod Dialihkan"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
msgstr ""
+"Tidak dapat menyambung, port mungkin sedang digunakan atau sambungan mungkin "
+"tidak sah."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Nodes Connected"
-msgstr ""
+msgstr "Nod Bersambung"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Nodes Disconnected"
-msgstr ""
+msgstr "Nod Diputuskan"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Set Animation"
@@ -4915,30 +4900,32 @@ msgstr "Tetapkan Animasi"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
-msgstr "Semua Pilihan"
+msgstr "Padam Nod"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "Padam Nod(-nod)"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Toggle Filter On/Off"
-msgstr ""
+msgstr "Togol Filter Hidup/Mati"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Change Filter"
-msgstr ""
+msgstr "Tukar Filter"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
msgstr ""
+"Tiada pemain animasi ditetapkan, jadi tidak dapat memperolehi semula nama "
+"trek."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
msgstr ""
+"Set laluan pemain tidak sah, jadi tidak dapat mendapatkan semula nama trek."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4946,15 +4933,16 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
+"Pemain animasi tidak mempunyai laluan nod akar yang sah, jadi tidak dapat "
+"mendapatkan semula nama trek."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Anim Clips"
-msgstr ""
+msgstr "Klip Anim"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Anim Tambah Trek"
+msgstr "Klip Audio"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Functions"
@@ -4963,132 +4951,132 @@ msgstr "Fungsi"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Node Renamed"
-msgstr ""
+msgstr "Nod Diubah Nama"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node..."
-msgstr ""
+msgstr "Tambah Nod..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "Edit Filtered Tracks:"
-msgstr ""
+msgstr "Edit Trek Difilter:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Enable Filtering"
-msgstr ""
+msgstr "Dayakan Penapisan"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
-msgstr ""
+msgstr "Togol Automain"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
-msgstr ""
+msgstr "Nama Animasi Baru:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Anim"
-msgstr ""
+msgstr "Anim Baru"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Animation Name:"
-msgstr ""
+msgstr "Tukar Nama Animasi:"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Animation?"
-msgstr ""
+msgstr "Padam Animasi?"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Remove Animation"
-msgstr ""
+msgstr "Alih Keluar Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Invalid animation name!"
-msgstr ""
+msgstr "Nama animasi tidak sah!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation name already exists!"
-msgstr ""
+msgstr "Nama animasi sudah wujud!"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Rename Animation"
-msgstr ""
+msgstr "Namakan Semula Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Next Changed"
-msgstr ""
+msgstr "Adun Berubah Seterusnya"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Change Blend Time"
-msgstr ""
+msgstr "Tukar Masa Blend"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Load Animation"
-msgstr ""
+msgstr "Muatkan Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Duplicate Animation"
-msgstr ""
+msgstr "Gandakan Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to copy!"
-msgstr ""
+msgstr "Tiada animasi untuk disalin!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation resource on clipboard!"
-msgstr ""
+msgstr "Tiada sumber animasi pada papan klip!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
-msgstr ""
+msgstr "Animasi Ditampal"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Paste Animation"
-msgstr ""
+msgstr "Tampal Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "No animation to edit!"
-msgstr ""
+msgstr "Tiada animasi untuk disunting!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
-msgstr ""
+msgstr "Mainkan animasi terpilih ke belakang dari pos semasa. (A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from end. (Shift+A)"
-msgstr ""
+msgstr "Mainkan animasi terpillih ke belakang dari hujung. (Shift+A)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Stop animation playback. (S)"
-msgstr ""
+msgstr "Hentikan playback animasi. (S)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from start. (Shift+D)"
-msgstr ""
+msgstr "Mainkan animasi terpilih dari awal. (Shift+D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation from current pos. (D)"
-msgstr ""
+msgstr "Mainkan animasi terpilih dar pos semasa. (D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation position (in seconds)."
-msgstr ""
+msgstr "Kedudukan animasi (dalam saat)."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Scale animation playback globally for the node."
-msgstr ""
+msgstr "Skala main balik animasi secara global untuk nod."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Tools"
-msgstr ""
+msgstr "Alat Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "Animasi"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
@@ -5101,39 +5089,39 @@ msgstr "Sunting Peralihan..."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Open in Inspector"
-msgstr ""
+msgstr "Buka dalam Inspektor"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
-msgstr ""
+msgstr "Paparkan senarai animasi dalam pemain."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Autoplay on Load"
-msgstr ""
+msgstr "Automain semasa Muatkan"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Enable Onion Skinning"
-msgstr ""
+msgstr "Aktifkan Kulit Bawang"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Onion Skinning Options"
-msgstr ""
+msgstr "Pilihan Kulit Bawang"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
-msgstr ""
+msgstr "Arah"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Past"
-msgstr ""
+msgstr "Sebelum"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr ""
+msgstr "Masa depan"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
-msgstr ""
+msgstr "Kedalaman"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
@@ -5149,50 +5137,50 @@ msgstr "3 langkah"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Differences Only"
-msgstr ""
+msgstr "Perbezaan Sahaja"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Force White Modulate"
-msgstr ""
+msgstr "Paksa Modulasi Putih"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Include Gizmos (3D)"
-msgstr ""
+msgstr "Sertakan Gizmos (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pin AnimationPlayer"
-msgstr ""
+msgstr "Pin AnimationPlayer"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
-msgstr ""
+msgstr "Cipta Animasi Baru"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation Name:"
-msgstr ""
+msgstr "Nama Animasi:"
#: 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 "Ralat!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Blend Times:"
-msgstr ""
+msgstr "Masa Adunan:"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Next (Auto Queue):"
-msgstr ""
+msgstr "Seterusnya (Baris Gilir Automatik):"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Cross-Animation Blend Times"
-msgstr ""
+msgstr "Masa Adunan Animasi Silang"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Move Node"
-msgstr ""
+msgstr "Pindahkan Nod"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Transition exists!"
@@ -5205,39 +5193,39 @@ msgstr "Tambah Peralihan"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "Tambah Nod"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
-msgstr ""
+msgstr "Akhir"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
-msgstr ""
+msgstr "Segera"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "Segerak"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
-msgstr ""
+msgstr "Pada Akhir"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr ""
+msgstr "Perjalanan"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Start and end nodes are needed for a sub-transition."
-msgstr ""
+msgstr "Nod mula dan tamat diperlukan untuk sub-peralihan."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "No playback resource set at path: %s."
-msgstr ""
+msgstr "Tiada sumber main balik ditetapkan pada laluan: %s."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Node Removed"
-msgstr ""
+msgstr "Nod Dikeluarkan"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Transition Removed"
@@ -5245,7 +5233,7 @@ msgstr "Peralihan Dikeluarkan"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
-msgstr ""
+msgstr "Tetapkan Nod Mula (Automain)"
#: editor/plugins/animation_state_machine_editor.cpp
msgid ""
@@ -5253,26 +5241,30 @@ msgid ""
"RMB to add new nodes.\n"
"Shift+LMB to create connections."
msgstr ""
+"Pilih dan pindah nod.\n"
+"RMB untuk menambah nod baru.\n"
+"Shift+LMB untuk membuat sambungan."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Create new nodes."
-msgstr ""
+msgstr "Cipta nod baru."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Connect nodes."
-msgstr ""
+msgstr "Hubungkan nod-nod."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Remove selected node or transition."
-msgstr ""
+msgstr "Alih keluar nod atau peralihan yang dipilih."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
+"Togol automain animasi ini semasa mula, mulakan semula atau cari ke sifar."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
-msgstr ""
+msgstr "Tetapkan hujung animasi. Ini adalah berguna untuk sub-peralihan."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Transition: "
@@ -5280,7 +5272,7 @@ msgstr "Peralihan: "
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Play Mode:"
-msgstr ""
+msgstr "Mod Main:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -5289,115 +5281,115 @@ msgstr "AnimationTree"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
-msgstr ""
+msgstr "Nama baru:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Scale:"
-msgstr ""
+msgstr "Skala:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Fade In (s):"
-msgstr ""
+msgstr "Pudar Masuk (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Fade Out (s):"
-msgstr ""
+msgstr "Pudar Keluar (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend"
-msgstr ""
+msgstr "Adun"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Mix"
-msgstr ""
+msgstr "Campur"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Auto Restart:"
-msgstr ""
+msgstr "Mula Semula Auto:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Restart (s):"
-msgstr ""
+msgstr "Mula Semula (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Random Restart (s):"
-msgstr ""
+msgstr "Mula Semula Rawak (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Start!"
-msgstr ""
+msgstr "Mula!"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Amount:"
-msgstr ""
+msgstr "Jumlah:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend 0:"
-msgstr ""
+msgstr "Adun 0:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend 1:"
-msgstr ""
+msgstr "Adun 1:"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "X-Fade Time (s):"
-msgstr ""
+msgstr "Masa X-Fade (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Current:"
-msgstr ""
+msgstr "Semasa:"
#: 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 "Tambah Input"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Clear Auto-Advance"
-msgstr ""
+msgstr "Kosongkan Auto-Advance"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Set Auto-Advance"
-msgstr ""
+msgstr "Tetapkan Auto-Advance"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Delete Input"
-msgstr ""
+msgstr "Padam Input"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is valid."
-msgstr ""
+msgstr "Pokok animasi sah."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation tree is invalid."
-msgstr ""
+msgstr "Pokok animasi tidak sah."
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Animation Node"
-msgstr ""
+msgstr "Nod Animasi"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "OneShot Node"
-msgstr ""
+msgstr "Nod OneShot"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Mix Node"
-msgstr ""
+msgstr "Campur Nod"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend2 Node"
-msgstr ""
+msgstr "Nod Blend2"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend3 Node"
-msgstr ""
+msgstr "Nod Blend3"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Blend4 Node"
-msgstr ""
+msgstr "Nod Blend4"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "TimeScale Node"
@@ -6336,6 +6328,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9700,7 +9693,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9708,19 +9701,59 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Tidak ada nama yang diberikan."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Komuniti"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Parameter Berubah"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Parameter Berubah"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komuniti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+"Adakah anda pasti anda mahu mengeluarkan semua sambungan dari isyarat ini?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Guna Set Semula"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9729,7 +9762,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Buang Trek Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Namakan Semula"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9737,50 +9800,143 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Parameter Berubah"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Menyimpan perubahan tempatan..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Parameter Berubah"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Komuniti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Commit List"
+msgstr "Komuniti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Ubah Nama Trek Anim"
+msgid "Branches"
+msgstr "Padanan:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Semua Pilihan"
+msgid "Create New Branch"
+msgstr "Cipta %s Baru"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Keluarkan Trek Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Semua Pilihan"
+msgid "Remotes"
+msgstr "Keluarkan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Cipta %s Baru"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Keluarkan Item"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Remote Name"
+msgstr "Nama Nod:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Keluarkan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Ubah Nama Trek Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Semua Pilihan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Pratonton:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12308,6 +12464,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13151,6 +13308,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animasi"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13163,6 +13353,84 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Menamakan semula folder:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Diri"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Tetapkan %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Dipinkan %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13179,6 +13447,21 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Tetapkan %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Fungsi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ubah saiz Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13188,6 +13471,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13196,6 +13483,63 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Muatkan Semula"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Pemalar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Pemalar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Pemalar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Pemalar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Padam Nod"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Penyuntingan Pokok Adegan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Diri"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Potong Nod"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13205,14 +13549,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Panggilan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Pemalar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Aksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Tab seterusnya"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Bingkai Fizik %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Isyarat"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Isyarat"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Contoh"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13789,7 +14193,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14002,7 +14415,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index 2aab12820b..0849aa8c03 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -20,13 +20,14 @@
# Lili Zoey <sayaks1@gmail.com>, 2021.
# slasken06 <ask.skivdal@gmail.com>, 2021.
# Daniel Skogly <daniel@klungo.no>, 2021.
+# Imre Kristoffer Eilertsen <imreeil42@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-26 17:18+0000\n"
-"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Imre Kristoffer Eilertsen <imreeil42@gmail.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb_NO/>\n"
"Language: nb\n"
@@ -109,7 +110,7 @@ msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr "Frigjør"
+msgstr "Fri"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
@@ -300,7 +301,7 @@ msgstr "Diskret"
#: editor/animation_track_editor.cpp
msgid "Trigger"
-msgstr "Avtrekker"
+msgstr "Utløser"
#: editor/animation_track_editor.cpp
msgid "Capture"
@@ -375,11 +376,12 @@ msgstr "Lag %d NYE spor og sett inn nøkler?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Create"
-msgstr "Lag"
+msgstr "Opprett"
#: editor/animation_track_editor.cpp
msgid "Anim Insert"
@@ -768,7 +770,7 @@ msgstr "Erstatt"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Erstatt Alle"
+msgstr "Erstatt alle"
#: editor/code_editor.cpp
msgid "Selection Only"
@@ -788,14 +790,14 @@ msgstr "Veksle skriptpanel"
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom In"
-msgstr "Zoom Inn"
+msgstr "Forstørr"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/sprite_frames_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 "Zoom Ut"
+msgstr "Zoom ut"
#: editor/code_editor.cpp
msgid "Reset Zoom"
@@ -849,12 +851,13 @@ msgstr "Scenen inneholder ikke noen skript."
#: 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 "Legg Til"
+msgstr "Legg til"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -905,8 +908,7 @@ msgstr "Kobler Til Signal:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -915,12 +917,11 @@ msgstr "Lukk"
#: editor/connections_dialog.cpp
msgid "Connect"
-msgstr "Koble Til"
+msgstr "Koble til"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
-msgstr "Signaler:"
+msgstr "Signal:"
#: editor/connections_dialog.cpp
msgid "Connect '%s' to '%s'"
@@ -942,7 +943,7 @@ msgstr "Koble Til..."
#: editor/connections_dialog.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Disconnect"
-msgstr "Koble Fra"
+msgstr "Koble fra"
#: editor/connections_dialog.cpp
#, fuzzy
@@ -992,7 +993,7 @@ msgstr "Endre %s type"
#: editor/create_dialog.cpp editor/project_settings_editor.cpp
msgid "Change"
-msgstr "Forandre"
+msgstr "Endre"
#: editor/create_dialog.cpp
msgid "Create New %s"
@@ -1214,7 +1215,7 @@ msgstr "Prosjektgrunnleggere"
#: editor/editor_about.cpp
msgid "Lead Developer"
-msgstr "Utviklingsleder"
+msgstr "Ledende utvikler"
#. TRANSLATORS: This refers to a job title.
#. The trailing space is used to distinguish with the project list application,
@@ -1229,7 +1230,7 @@ msgstr "Utviklere"
#: editor/editor_about.cpp
msgid "Authors"
-msgstr "Forfattere"
+msgstr "Skapere"
#: editor/editor_about.cpp
msgid "Platinum Sponsors"
@@ -1343,7 +1344,7 @@ msgstr "Vellykket Installering av Pakke!"
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr "Vellykket!"
+msgstr "Suksess!"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1413,7 +1414,7 @@ msgstr "Demp"
#: editor/editor_audio_buses.cpp
msgid "Bypass"
-msgstr "Omgå"
+msgstr "Forbipasser"
#: editor/editor_audio_buses.cpp
#, fuzzy
@@ -1423,7 +1424,7 @@ msgstr "Bus valg"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr "Duplisér"
+msgstr "Dupliser"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -1479,7 +1480,7 @@ msgstr "Det finnes ingen «%s»-fil"
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
msgid "Layout"
-msgstr "Layout"
+msgstr "Utforming"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -1612,7 +1613,7 @@ msgstr "Legg til AutoLoad"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/script_create_dialog.cpp scene/gui/file_dialog.cpp
msgid "Path:"
-msgstr "Bane:"
+msgstr "Filbane:"
#: editor/editor_autoload_settings.cpp
msgid "Node Name:"
@@ -1668,7 +1669,7 @@ msgstr "Velg en Mappe"
#: editor/filesystem_dock.cpp editor/project_manager.cpp
#: scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr "Lag Mappe"
+msgstr "Opprett mappe"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
@@ -1878,9 +1879,8 @@ msgid "(Editor Disabled)"
msgstr "Avslått"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "Beskrivelse:"
+msgstr "Alternativer for klasse:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
@@ -1916,9 +1916,8 @@ msgid "Error saving profile to path: '%s'."
msgstr "Feil ved lagring av profilen til stien: '%s'."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Reset to Default"
-msgstr "Last Standard"
+msgstr "Tilbakestill til standarder"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1948,7 +1947,7 @@ msgstr "Gjeldende:"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
msgid "Import"
-msgstr "importer"
+msgstr "Importer"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
@@ -1984,9 +1983,8 @@ msgid "Import Profile(s)"
msgstr "%d flere filer"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Export Profile"
-msgstr "Eksporter Prosjekt"
+msgstr "Eksporter Profil"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -2027,7 +2025,6 @@ msgid "New Folder..."
msgstr "Ny Mappe..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Oppdater"
@@ -2069,11 +2066,11 @@ msgstr "Lagre ei fil"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr "GÃ¥ Tilbake"
+msgstr "GÃ¥ tilbake"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr "GÃ¥ Fremover"
+msgstr "GÃ¥ fremover"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
@@ -2150,7 +2147,8 @@ msgstr "Mapper og Filer:"
msgid "Preview:"
msgstr "Forhåndsvisning:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fil:"
@@ -2218,27 +2216,24 @@ msgid "Theme Properties"
msgstr "Egenskaper"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Colors"
-msgstr "Farge"
+msgstr "Farger"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constants"
msgstr "Konstanter"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Fonts"
-msgstr "Font"
+msgstr "Skrifttyper"
#: editor/editor_help.cpp editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Icons"
-msgstr "Ikon"
+msgstr "Ikoner"
#: editor/editor_help.cpp
msgid "Styles"
-msgstr ""
+msgstr "Stiler"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2282,17 +2277,15 @@ msgstr "Søk Hjelp"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
-msgstr "Forskjell på små og store bokstaver"
+msgstr "Skilling mellom store/små bokstaver"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "Vis hjelpere"
+msgstr "Vis hierarki"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Display All"
-msgstr "Erstatt Alle"
+msgstr "Vis alle"
#: editor/editor_help_search.cpp
#, fuzzy
@@ -2334,23 +2327,20 @@ msgid "Class"
msgstr "Klasse"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "Metoder"
+msgstr "Metode"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "Signaler"
+msgstr "Signal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstant"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "Egenskap:"
+msgstr "Egenskap"
#: editor/editor_help_search.cpp
#, fuzzy
@@ -2376,6 +2366,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2409,7 +2401,7 @@ msgstr "Kopier Skript-Sti"
#: editor/editor_log.cpp
msgid "Output:"
-msgstr "Output:"
+msgstr "Utgang:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -2433,7 +2425,7 @@ msgstr "Nullstill Resultat"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
msgid "Stop"
-msgstr "Stopp"
+msgstr "Stopp avspilling"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
@@ -2445,13 +2437,12 @@ msgid "%s/s"
msgstr "%s/s"
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
-msgstr "Last ned"
+msgstr "Ned"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr "Oppover"
+msgstr "Opp"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2977,9 +2968,8 @@ msgid "Play This Scene"
msgstr "Spill Scene"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "Lukk Andre Faner"
+msgstr "Lukk fanen"
#: editor/editor_node.cpp
#, fuzzy
@@ -2995,9 +2985,8 @@ msgid "Close Tabs to the Right"
msgstr "Lukk faner til høyre"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "Lukk Alle"
+msgstr "Lukk alle faner"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -3074,7 +3063,7 @@ msgstr "Ã…pne Scene..."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Open Recent"
-msgstr "Ã…pne Nylig"
+msgstr "Ã…pne nylig brukte"
#: editor/editor_node.cpp
msgid "Save Scene"
@@ -3100,7 +3089,7 @@ msgstr "Angre"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr "Gjenta"
+msgstr "Gjør om"
#: editor/editor_node.cpp
#, fuzzy
@@ -3131,17 +3120,17 @@ msgid "Shut Down Version Control"
msgstr "Steng ned versjonskontroll"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "Eksporter"
+msgstr "Eksporter..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Ã…pne prosjektdatamappe"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Ã…pne Redigererdatamappen"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3164,7 +3153,7 @@ msgstr "Avslutt til Prosjektliste"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr "Feilsøk"
+msgstr "Avlus"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -3278,7 +3267,7 @@ msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
-msgstr "Redigeringsverktøy"
+msgstr "Redaktør"
#: editor/editor_node.cpp
msgid "Editor Settings..."
@@ -3290,7 +3279,7 @@ msgstr "Redigeringsverktøy Layout"
#: editor/editor_node.cpp
msgid "Take Screenshot"
-msgstr "Ta Skjermbilde"
+msgstr "Ta skjermbilde"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
@@ -3301,11 +3290,6 @@ msgid "Toggle Fullscreen"
msgstr "Veksle Fullskjerm"
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Veksle modus"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Åpne data for redigeringsverktøy/innstillingsmappe"
@@ -3355,7 +3339,7 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "Fellesskap"
+msgstr "Samfunn"
#: editor/editor_node.cpp
#, fuzzy
@@ -3442,7 +3426,7 @@ msgstr "Utvid Nederste Panel"
#: editor/editor_node.cpp
msgid "Output"
-msgstr "Output"
+msgstr "Utgang"
#: editor/editor_node.cpp
msgid "Don't Save"
@@ -3497,7 +3481,7 @@ msgstr "Eksporter Mal-Manager"
#: editor/editor_node.cpp modules/gltf/editor_scene_exporter_gltf_plugin.cpp
msgid "Export Library"
-msgstr "Eksporter Bibliotek"
+msgstr "Eksporter bibliotek"
#: editor/editor_node.cpp
msgid "Merge With Existing"
@@ -3523,7 +3507,7 @@ msgstr ""
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Reload"
-msgstr "Gjeninnlat"
+msgstr "Oppdater"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -3540,6 +3524,7 @@ msgid "Load Errors"
msgstr "Last feil"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Velg"
@@ -3613,20 +3598,17 @@ msgid "Update"
msgstr "Oppdater"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Version"
-msgstr "Versjon:"
+msgstr "Versjon"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Author"
-msgstr "Forfattere"
+msgstr "Forfatter"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
-msgstr ""
+msgstr "Status"
#: editor/editor_profiler.cpp
msgid "Measure:"
@@ -3673,14 +3655,12 @@ msgid "Frame #:"
msgstr "Bilde #:"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Time"
-msgstr "Tid:"
+msgstr "Tid"
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Calls"
-msgstr "Ring"
+msgstr "Samtaler"
#: editor/editor_properties.cpp
#, fuzzy
@@ -3858,9 +3838,8 @@ msgid "Select Node(s) to Import"
msgstr "Velg node(r) som skal importeres"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Browse"
-msgstr "Bla gjennom"
+msgstr "See gjennom"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
@@ -3870,6 +3849,12 @@ msgstr "Scene-Sti:"
msgid "Import From Node:"
msgstr "Importer Fra Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Feil!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -3969,7 +3954,7 @@ msgstr ""
#: editor/export_template_manager.cpp
msgid "Disconnected"
-msgstr "Frakoblet"
+msgstr "Koblet fra"
#: editor/export_template_manager.cpp
msgid "Resolving"
@@ -3982,7 +3967,7 @@ msgstr "Kan ikke Løses"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Connecting..."
-msgstr "Kobler til..."
+msgstr "Kobler til…"
#: editor/export_template_manager.cpp
#, fuzzy
@@ -4057,7 +4042,7 @@ msgstr "Eksporter Mal-Manager"
#: editor/export_template_manager.cpp
msgid "Current Version:"
-msgstr "Gjeldende Versjon:"
+msgstr "Nåværende versjon:"
#: editor/export_template_manager.cpp
msgid "Export templates are missing. Download them or install from a file."
@@ -4068,9 +4053,8 @@ msgid "Export templates are installed and ready to be used."
msgstr ""
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Open Folder"
-msgstr "Ã…pne en fil"
+msgstr "Åpne mappe…"
#: editor/export_template_manager.cpp
msgid "Open the folder containing installed templates for the current version."
@@ -4160,9 +4144,8 @@ msgid ""
msgstr ""
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Favorites"
-msgstr "Favoritter:"
+msgstr "Favoritter"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
@@ -4266,14 +4249,12 @@ msgid "Instance"
msgstr "Instans"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
-msgstr "Favoritter:"
+msgstr "Legg til i favoritter"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Remove from Favorites"
-msgstr "Fjern fra Gruppe"
+msgstr "Fjern fra favoritter"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
@@ -4305,16 +4286,14 @@ msgstr "Lagre Ressurs Som..."
#: editor/filesystem_dock.cpp editor/inspector_dock.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Expand All"
msgstr "Utvid alle"
#: editor/filesystem_dock.cpp editor/inspector_dock.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Collapse All"
-msgstr "Kollaps alle"
+msgstr "Fold sammen alle"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -4352,7 +4331,7 @@ msgstr "Duplisér"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
-msgstr "Endre Navn..."
+msgstr "Gi nytt navn..."
#: editor/filesystem_dock.cpp
msgid "Focus the search box"
@@ -4378,9 +4357,8 @@ msgid "Toggle Split Mode"
msgstr "Veksle modus"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Search files"
-msgstr "Søk i klasser"
+msgstr "Søk i filer"
#: editor/filesystem_dock.cpp
msgid ""
@@ -4399,7 +4377,7 @@ msgstr "Flytt"
#: editor/project_manager.cpp editor/rename_dialog.cpp
#: editor/scene_tree_dock.cpp
msgid "Rename"
-msgstr "Endre navn"
+msgstr "Gi nytt navn"
#: editor/filesystem_dock.cpp
msgid "Overwrite"
@@ -4416,21 +4394,19 @@ msgstr "Opprett skript"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
msgid "Find in Files"
-msgstr "Finn i Filer"
+msgstr "Finn i filer"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find:"
-msgstr "Finn"
+msgstr "Finn:"
#: editor/find_in_files.cpp editor/rename_dialog.cpp
msgid "Replace:"
msgstr "Erstatt:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Folder:"
-msgstr "Lag mappe"
+msgstr "Mappe:"
#: editor/find_in_files.cpp
#, fuzzy
@@ -4471,9 +4447,8 @@ msgid "Replace All (NO UNDO)"
msgstr "Erstatt Alle"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Searching..."
-msgstr "Lagrer..."
+msgstr "Søker …"
#: editor/find_in_files.cpp
#, fuzzy
@@ -4546,9 +4521,8 @@ msgid "Group Editor"
msgstr "Redigeringsverktøy for grupper"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Manage Groups"
-msgstr "Grupper"
+msgstr "HÃ¥ndter grupper"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Single Scene"
@@ -4680,9 +4654,8 @@ msgid "Import As:"
msgstr "Importer Som:"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Preset"
-msgstr "Preset..."
+msgstr "Forhåndsinnstilling"
#: editor/import_dock.cpp
#, fuzzy
@@ -4819,15 +4792,15 @@ msgid "Create a Plugin"
msgstr "Lag Omriss"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Plugin Name:"
-msgstr "Plugins"
+msgstr "Navn på tillegg:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
msgstr "Undermappe:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Forfatter:"
@@ -4909,9 +4882,8 @@ msgstr "Legg til Animasjon"
#: 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 "Last"
+msgstr "Last..."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4982,9 +4954,8 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Point"
-msgstr "Flytt Punkt"
+msgstr "Punkt"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -5068,7 +5039,7 @@ msgstr "Forandre"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Edit Filters"
-msgstr "Rediger Filtre"
+msgstr "Rediger filtere"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
@@ -5293,7 +5264,7 @@ msgstr "Animasjon"
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "New"
-msgstr "Ny"
+msgstr "Nye"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -5333,7 +5304,7 @@ msgstr "Fortid"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Future"
-msgstr "Framtid"
+msgstr "Fremtid"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Depth"
@@ -5418,7 +5389,7 @@ msgstr "Legg til node"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
-msgstr "Slutt"
+msgstr "End"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
@@ -5426,7 +5397,7 @@ msgstr "Umiddelbart"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "Synkroniser"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
@@ -5434,7 +5405,7 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr ""
+msgstr "Reise"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Start and end nodes are needed for a sub-transition."
@@ -5521,13 +5492,12 @@ msgid "Fade Out (s):"
msgstr "Fade Ut (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
-#, fuzzy
msgid "Blend"
-msgstr "Blend"
+msgstr "Bland"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Mix"
-msgstr "Bland"
+msgstr "Miks"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Auto Restart:"
@@ -5564,13 +5534,13 @@ msgstr "X-Fade Tid (s):"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Current:"
-msgstr "Gjeldende:"
+msgstr "Aktiv:"
#: 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 "Legg til Input"
+msgstr "Legg til inndata"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#, fuzzy
@@ -5751,9 +5721,8 @@ msgid "Downloading (%s / %s)..."
msgstr "Laster ned"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Downloading..."
-msgstr "Laster ned"
+msgstr "Laster ned..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Resolving..."
@@ -5779,7 +5748,7 @@ msgstr "Prøv på nytt"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Download Error"
-msgstr "Nedlastningsfeil"
+msgstr "Feil ved nedlasting"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5788,7 +5757,7 @@ msgstr "Nedlastning for denne asset'en er allerede i gang!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "Nylig oppdatert"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
@@ -5813,14 +5782,12 @@ msgid "License (Z-A)"
msgstr "Lisens"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "First"
-msgstr "første"
+msgstr "Første"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Previous"
-msgstr "Forrige fane"
+msgstr "Forrige"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Next"
@@ -5843,9 +5810,8 @@ msgid "Search assets (excluding templates, projects, and demos)"
msgstr ""
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Import..."
-msgstr "Importer"
+msgstr "Importer..."
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5865,9 +5831,8 @@ msgid "Site:"
msgstr "Side:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Support"
-msgstr "Support..."
+msgstr "Støtte"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -5878,9 +5843,8 @@ msgid "Testing"
msgstr "Tester"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Loading..."
-msgstr "Last"
+msgstr "Laster..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -5933,7 +5897,7 @@ msgstr "Velg malfil"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Preview"
-msgstr "Forhåndsvis"
+msgstr "Forhåndvisning"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
@@ -6053,9 +6017,8 @@ msgstr "Endre CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Locked"
-msgstr "Slett Valgte"
+msgstr "LÃ¥st"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6080,29 +6043,24 @@ msgid ""
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Left"
-msgstr "Venstre"
+msgstr "Øverst til venstre"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Right"
-msgstr "Høyre"
+msgstr "Øverst til høyre"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Right"
-msgstr "Roter Polygon"
+msgstr "Nederst til høyre"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Left"
-msgstr "Bunnvisning"
+msgstr "Nederst til venstre"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Left"
-msgstr "Innrykk Venstre"
+msgstr "I midten til venstre"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -6110,9 +6068,8 @@ msgid "Center Top"
msgstr "Plasser Utvalg I Midten"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Right"
-msgstr "Innrykk Høyre"
+msgstr "I midten til høyre"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -6121,7 +6078,7 @@ msgstr "Plasser Utvalg I Midten"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
-msgstr ""
+msgstr "I midten"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -6249,7 +6206,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Reset"
-msgstr "Zoom Resett"
+msgstr "Tilbakestill forstørring"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6475,7 +6432,7 @@ msgstr "Fjern Ben"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View"
-msgstr "Visning"
+msgstr "Vis"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Always Show Grid"
@@ -6636,6 +6593,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Legg til %s"
@@ -6697,9 +6655,8 @@ msgstr ""
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "Omstart NÃ¥"
+msgstr "Omstart"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -6818,9 +6775,8 @@ msgid "Right Linear"
msgstr "Høyrelineær"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Load Preset"
-msgstr "Last Ressurs"
+msgstr "Åpne forhåndsinnstilling"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Remove Curve Point"
@@ -7073,7 +7029,7 @@ msgstr "MeshBibliotek..."
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Add Item"
-msgstr "Legg til Element"
+msgstr "Legg til en gjenstand"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Remove Selected Item"
@@ -7345,7 +7301,7 @@ msgstr "Legg til Punkt (i tomt rom)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Delete Point"
-msgstr "Fjern Punkt"
+msgstr "Slett punkt"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -7495,9 +7451,8 @@ msgid "UV"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Points"
-msgstr "Flytt Punkt"
+msgstr "Poeng"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -7586,7 +7541,7 @@ msgstr "Fjern UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Settings"
-msgstr "Rutenettsinnstillinger"
+msgstr "Instillinger for rutenett"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
@@ -7765,9 +7720,8 @@ msgid "New Text File..."
msgstr "Ny Mappe..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
-msgstr "Ã…pne en fil"
+msgstr "Ã…pne fil"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7805,7 +7759,7 @@ msgstr "Feil ved lagring"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
-msgstr "Lagre Tema Som..."
+msgstr "Lagre drakt som …"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7815,12 +7769,12 @@ msgstr "%s-klassereferanse"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr "Finn Neste"
+msgstr "Finn neste"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Previous"
-msgstr "Finn Forrige"
+msgstr "Finn forrige"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7838,19 +7792,19 @@ msgstr "Lim inn Noder"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
-msgstr "Sorter"
+msgstr "Sortering"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Up"
-msgstr "Flytt Opp"
+msgstr "Flytt opp"
#: 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 "Flytt Ned"
+msgstr "Flytt ned"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7877,7 +7831,7 @@ msgstr "Gjenåpne Lukket Skript"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr "Lagre Alt"
+msgstr "Lagre alle"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
@@ -7915,7 +7869,7 @@ msgstr "Lagre drakt"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
-msgstr "Lukk Alle"
+msgstr "Lukk alle"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Docs"
@@ -7935,15 +7889,15 @@ msgstr "Søk"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr "Tre Inn I"
+msgstr "Stepp Inn i"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
-msgstr "Hopp Over"
+msgstr "Stepp over"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
-msgstr "Brekk"
+msgstr "Stopp"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
@@ -7993,12 +7947,11 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
-msgstr "Feilsøking"
+msgstr "Feilsøkingsprogram"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Search Results"
-msgstr "Søk hjelp"
+msgstr "Søkeresultater"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -8011,13 +7964,12 @@ msgid "Connections to method:"
msgstr "Koble Til Node:"
#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source"
-msgstr "Ressurs"
+msgstr "Kilde"
#: editor/plugins/script_text_editor.cpp
msgid "Target"
-msgstr ""
+msgstr "MÃ¥l"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -8030,9 +7982,8 @@ msgid "[Ignore]"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Line"
-msgstr "Linje:"
+msgstr "Linje"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Function"
@@ -8069,7 +8020,7 @@ msgstr "Små bokstaver"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Capitalize"
-msgstr "Store bokstaver"
+msgstr "Stor forbokstav"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
@@ -8078,27 +8029,26 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "Bokmerker"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Slett punkter"
+msgstr "Stoppunkter"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "GÃ¥ til"
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Cut"
-msgstr "Klipp ut"
+msgstr "Kutt"
#: editor/plugins/script_text_editor.cpp editor/plugins/theme_editor_plugin.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Select All"
-msgstr "Velg Alle"
+msgstr "Velg alle"
#: editor/plugins/script_text_editor.cpp
msgid "Delete Line"
@@ -8196,7 +8146,7 @@ msgstr "GÃ¥ til Linje"
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr ""
+msgstr "Slå av/på stoppunkt"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
@@ -8368,20 +8318,17 @@ msgid "None"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Rotate"
-msgstr "Roter Modus"
+msgstr "Roter"
#. TRANSLATORS: This refers to the movement that changes the position of an object.
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Translate"
-msgstr "Oversettelser"
+msgstr "Oversett"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale"
-msgstr "Skala:"
+msgstr "Skala"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scaling: "
@@ -8727,7 +8674,7 @@ msgstr "Last Standard"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform"
-msgstr ""
+msgstr "Transformer"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
@@ -8785,7 +8732,7 @@ msgstr "Rediger Poly"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Settings..."
-msgstr "Innstillinger …"
+msgstr "Innstillinger…"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -8841,11 +8788,11 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pre"
-msgstr ""
+msgstr "Pre"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Post"
-msgstr ""
+msgstr "Send"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unnamed Gizmo"
@@ -9022,7 +8969,7 @@ msgstr "Hastighet (FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr ""
+msgstr "Repeter"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -9108,7 +9055,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Offset:"
-msgstr ""
+msgstr "Avstand:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
@@ -9200,9 +9147,8 @@ msgid "Finalizing"
msgstr "Analyserer"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Filter:"
-msgstr "Lim inn Noder"
+msgstr "Filter:"
#: editor/plugins/theme_editor_plugin.cpp
msgid "With Data"
@@ -9304,9 +9250,8 @@ msgid "Select all Theme items with item data."
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Deselect All"
-msgstr "Velg Alle"
+msgstr "Velg ingen"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Deselect all Theme items."
@@ -9435,9 +9380,8 @@ msgid "Edit Items"
msgstr "Rediger Variabel:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Types:"
-msgstr "Type:"
+msgstr "Typer:"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -9483,9 +9427,8 @@ msgid "Old Name:"
msgstr "Nodenavn:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Import Items"
-msgstr "Importer Tema"
+msgstr "Importer gjenstander"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -9626,7 +9569,7 @@ msgstr "Deaktivert"
#: editor/plugins/theme_editor_preview.cpp
msgid "Item"
-msgstr ""
+msgstr "Oppføring"
#: editor/plugins/theme_editor_preview.cpp
#, fuzzy
@@ -9656,7 +9599,7 @@ msgstr ""
#: editor/plugins/theme_editor_preview.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Undermeny"
#: editor/plugins/theme_editor_preview.cpp
#, fuzzy
@@ -9700,7 +9643,7 @@ msgstr "Rediger Variabel:"
#: editor/plugins/theme_editor_preview.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Undertre"
#: editor/plugins/theme_editor_preview.cpp
#, fuzzy
@@ -9752,7 +9695,7 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Bucket Fill"
-msgstr ""
+msgstr "Bøttefylling"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
@@ -9764,7 +9707,7 @@ msgstr "Finn Flis"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr ""
+msgstr "Transposer"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
@@ -9806,19 +9749,19 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Left"
-msgstr "Roter til Venstre"
+msgstr "Roter til venstre"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Right"
-msgstr "Roter til Høyre"
+msgstr "Roter til høyre"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
-msgstr ""
+msgstr "Vend horisontalt"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Vertically"
-msgstr ""
+msgstr "Vend loddrett"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Clear Transform"
@@ -9873,9 +9816,8 @@ msgid "Select the previous shape, subtile, or Tile."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region"
-msgstr "Roter Modus"
+msgstr "Region"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -9897,9 +9839,8 @@ msgid "Bitmask"
msgstr "Roter Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority"
-msgstr "Eksporter Prosjekt"
+msgstr "Prioritet"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon"
@@ -10192,7 +10133,7 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10200,19 +10141,58 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Ingen navn gitt."
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
-msgstr "Fellesskap"
+msgstr "Sjekk inn"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Forandre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Forandre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Sjekk inn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Undertre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Er du sikker på at du vil åpne mer enn ett prosjekt?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Nullstill Zoom"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -10222,7 +10202,37 @@ msgid "Initialize"
msgstr "Store bokstaver"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Fjern punkt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Gi nytt navn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10231,55 +10241,147 @@ msgid "Detect new changes"
msgstr "Lag ny %s"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Endringer"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Lukke og lagre endringer?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Lagrer lokale endringer..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Forandre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Sjekk inn endringer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Sjekk inn endringer"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Sjekk inn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Endre navn"
+msgid "Branches"
+msgstr "Treff:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Slett"
+msgid "Create New Branch"
+msgstr "Opprett Nytt Prosjekt"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Forandre"
+msgid "Remove Branch"
+msgstr "Fjern Anim-Spor"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Slett Valgte"
+msgid "Remotes"
+msgstr "Ekstern"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Lagre Alle"
+msgid "Create New Remote"
+msgstr "Opprett Nytt Prosjekt"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Synkroniser Skriptforandringer"
+msgid "Remove Remote"
+msgstr "Fjern Gjenstand"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Remote Name"
+msgstr "Fjern-funksjon "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Fjern-funksjon "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
msgstr ""
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr "Endret"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Endre navn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Slettet"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Forandre"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Vis"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Splitt Sti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unified"
+msgstr "Endret"
+
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
msgstr ""
@@ -10300,7 +10402,7 @@ msgstr "Vektor"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "Boolsk verdi"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sampler"
@@ -10406,9 +10508,8 @@ msgid "Fragment"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Light"
-msgstr "Høyre"
+msgstr "Lys"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -11135,7 +11236,7 @@ msgstr "Kjørbar"
#: editor/project_export.cpp
msgid "Delete preset '%s'?"
-msgstr ""
+msgstr "Slett forhåndsinnstillingen «%s»?"
#: editor/project_export.cpp
msgid ""
@@ -11152,7 +11253,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Release"
-msgstr ""
+msgstr "Slipp"
#: editor/project_export.cpp
#, fuzzy
@@ -11169,11 +11270,11 @@ msgstr ""
#: editor/project_export.cpp
msgid "Presets"
-msgstr ""
+msgstr "Forhåndsinnstillinger"
#: editor/project_export.cpp editor/project_settings_editor.cpp
msgid "Add..."
-msgstr ""
+msgstr "Legg til…"
#: editor/project_export.cpp
msgid ""
@@ -11224,7 +11325,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr "Egenskaper"
+msgstr "Funksjoner"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -11235,9 +11336,8 @@ msgid "Feature List:"
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Script"
-msgstr "Kjør Skript"
+msgstr "Skript"
#: editor/project_export.cpp
#, fuzzy
@@ -11246,7 +11346,7 @@ msgstr "Eksporter Prosjekt"
#: editor/project_export.cpp
msgid "Text"
-msgstr ""
+msgstr "Tekst"
#: editor/project_export.cpp
msgid "Compiled Bytecode (Faster Loading)"
@@ -11583,7 +11683,7 @@ msgstr ""
#. TRANSLATORS: This refers to the application where users manage their Godot projects.
#: editor/project_manager.cpp
msgid "Project Manager"
-msgstr "Prosjektstyring"
+msgstr "Prosjekthåndterer"
#: editor/project_manager.cpp
#, fuzzy
@@ -11597,7 +11697,7 @@ msgstr "Henter fillager, vennligst vent..."
#: editor/project_manager.cpp
msgid "Last Modified"
-msgstr ""
+msgstr "Sist endret"
#: editor/project_manager.cpp
#, fuzzy
@@ -11611,7 +11711,7 @@ msgstr "Endre Navn på Prosjekt"
#: editor/project_manager.cpp
msgid "Scan"
-msgstr "Gjennomsøk"
+msgstr "Skann"
#: editor/project_manager.cpp
#, fuzzy
@@ -11624,7 +11724,7 @@ msgstr "Velg en mappe å søke gjennom"
#: editor/project_manager.cpp
msgid "New Project"
-msgstr "Nytt Prosjekt"
+msgstr "Nytt prosjekt"
#: editor/project_manager.cpp
#, fuzzy
@@ -11652,12 +11752,11 @@ msgstr "Ressursbibliotek"
#: editor/project_manager.cpp
msgid "Restart Now"
-msgstr "Omstart NÃ¥"
+msgstr "Start på nytt nå"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove All"
-msgstr "Fjern Funksjon"
+msgstr "Fjern alle"
#: editor/project_manager.cpp
msgid "Also delete project contents (no undo!)"
@@ -11777,14 +11876,12 @@ msgid "Wheel Right Button"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 1"
-msgstr "Museknapp"
+msgstr "X knapp 1"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "X Button 2"
-msgstr "Museknapp"
+msgstr "X knapp 2"
#: editor/project_settings_editor.cpp
msgid "Joypad Axis Index:"
@@ -11852,9 +11949,8 @@ msgid "Setting '%s' is internal, and it can't be deleted."
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Delete Item"
-msgstr "Slett Valgte"
+msgstr "Slett objektet"
#: editor/project_settings_editor.cpp
msgid ""
@@ -11962,7 +12058,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Localization"
-msgstr ""
+msgstr "Lokalisering"
#: editor/project_settings_editor.cpp
msgid "Translations"
@@ -11986,7 +12082,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr ""
+msgstr "Språk"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -12017,7 +12113,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr "Innstikkmoduler"
+msgstr "Plugins"
#: editor/project_settings_editor.cpp
#, fuzzy
@@ -12050,7 +12146,7 @@ msgstr ""
#: editor/property_editor.cpp
msgid "Assign"
-msgstr "Tildel"
+msgstr "Knytt"
#: editor/property_editor.cpp
msgid "Select Node"
@@ -12099,9 +12195,8 @@ msgid "Use Regular Expressions"
msgstr "Gjeldende Versjon:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "Snapping innstillinger"
+msgstr "Avanserte alternativer"
#: editor/rename_dialog.cpp
msgid "Substitute"
@@ -12149,9 +12244,8 @@ msgid "Initial value for the counter"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Step"
-msgstr "Steg:"
+msgstr "Steg"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
@@ -12159,7 +12253,7 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Padding"
-msgstr ""
+msgstr "Fyll"
#: editor/rename_dialog.cpp
msgid ""
@@ -12173,11 +12267,11 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Style"
-msgstr ""
+msgstr "Stil"
#: editor/rename_dialog.cpp
msgid "Keep"
-msgstr ""
+msgstr "Behold"
#: editor/rename_dialog.cpp
msgid "PascalCase to snake_case"
@@ -12202,9 +12296,8 @@ msgid "To Uppercase"
msgstr "Store versaler"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Reset"
-msgstr "Nullstill Zoom"
+msgstr "Tilbakestill"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -12563,9 +12656,8 @@ msgid "Detach the script from the selected node."
msgstr "Instanser den valgte scene(r) som barn av den valgte noden."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Remote"
-msgstr "Fjern Funksjon"
+msgstr "Ekstern"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -12576,7 +12668,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Local"
-msgstr ""
+msgstr "Lokal"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance? (No Undo!)"
@@ -12643,7 +12735,7 @@ msgstr ""
#: editor/scene_tree_editor.cpp
msgid "Toggle Visibility"
-msgstr ""
+msgstr "Juster synlighet"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -12725,7 +12817,7 @@ msgstr "Overskriv"
#: editor/script_create_dialog.cpp
msgid "N/A"
-msgstr ""
+msgstr "Ikke aktuelt"
#: editor/script_create_dialog.cpp
msgid "Open Script / Choose Location"
@@ -12802,9 +12894,8 @@ msgid "Class Name:"
msgstr "Klasse:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Template:"
-msgstr "Fjern Mal"
+msgstr "Mal:"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -12825,9 +12916,8 @@ msgid "Bytes:"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Warning:"
-msgstr "Advarsler:"
+msgstr "Advarsel:"
#: editor/script_editor_debugger.cpp
msgid "Error:"
@@ -12847,9 +12937,8 @@ msgid "C++ Source"
msgstr "Ressurs"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source:"
-msgstr "Ressurs"
+msgstr "Kildekode:"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -12862,7 +12951,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Errors"
-msgstr ""
+msgstr "Feil"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -12871,7 +12960,7 @@ msgstr "Frakoblet"
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr "Kopier feil"
+msgstr "Feil ved kopiering"
#: editor/script_editor_debugger.cpp
msgid "Open C++ Source on GitHub"
@@ -12908,7 +12997,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Monitor"
-msgstr ""
+msgstr "Skjerm"
#: editor/script_editor_debugger.cpp
msgid "Value"
@@ -12916,7 +13005,7 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Monitors"
-msgstr ""
+msgstr "Skjermer"
#: editor/script_editor_debugger.cpp
msgid "Pick one or more items from the list to display the graph."
@@ -12936,24 +13025,25 @@ msgid "Export list to a CSV file"
msgstr "Eksporter Prosjekt"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Type"
-msgstr ""
+msgstr "Skriv"
#: editor/script_editor_debugger.cpp
msgid "Format"
-msgstr ""
+msgstr "Format"
#: editor/script_editor_debugger.cpp
msgid "Usage"
-msgstr ""
+msgstr "Bruk"
#: editor/script_editor_debugger.cpp
msgid "Misc"
-msgstr ""
+msgstr "Diverse"
#: editor/script_editor_debugger.cpp
msgid "Clicked Control:"
@@ -12995,7 +13085,7 @@ msgstr "Innstillinger for redigeringsverktøy"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
-msgstr ""
+msgstr "Snarveier"
#: editor/settings_config_dialog.cpp
msgid "Binding"
@@ -13118,7 +13208,7 @@ msgstr ""
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Platform"
-msgstr ""
+msgstr "Plattform"
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Dynamic Library"
@@ -13143,7 +13233,7 @@ msgstr "Deaktiver Oppdateringsspinner"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Library"
-msgstr ""
+msgstr "Bibliotek"
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Libraries: "
@@ -13365,9 +13455,8 @@ msgid "Indirect lighting"
msgstr "Innrykk Høyre"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
-msgstr "Gjeldende Versjon:"
+msgstr "Etterbehandling"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
#, fuzzy
@@ -13450,7 +13539,7 @@ msgstr ""
#: modules/navigation/navigation_mesh_generator.cpp
msgid "Done!"
-msgstr "Ferdig!"
+msgstr "Ferdig"
#: modules/visual_script/visual_script.cpp
msgid ""
@@ -13805,7 +13894,7 @@ msgstr "Velg eller lag en funksjon for å redigere graf"
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr "Slett Valgte"
+msgstr "Slett valgt"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
@@ -13831,6 +13920,40 @@ msgstr "Oppdater Graf"
msgid "Edit Member"
msgstr "Rediger Medlem"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Gjeldende Versjon:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animasjon"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tilførseltype ikke itererbar: "
@@ -13843,6 +13966,87 @@ msgstr "Iterator ble ugyldig"
msgid "Iterator became invalid: "
msgstr "Iterator ble ugyldig: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Ender mappenavn:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Bryter"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Typer:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Selv"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Gyldige karakterer:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Legg til %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Legg til %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13859,6 +14063,20 @@ msgstr "Sti leder ikke Node!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ugyldig navn for indeksegenskap '%s' i noden %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funksjoner"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Endre størrelsen på Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Ugyldig argument av type: "
@@ -13868,6 +14086,10 @@ msgid ": Invalid arguments: "
msgstr ": Ugyldige argumenter: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13876,6 +14098,65 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Oppdater"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Panorerings-Modus"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Panorerings-Modus"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TidSøk Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Lagre Scene"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Selv"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Klipp ut Noder"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13885,15 +14166,77 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Samtaler"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstanter"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Lag Ben"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Lag Ben"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Handling"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Lim inn Noder"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Flytt Modus"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fysikk-Frame %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instans"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13932,9 +14275,8 @@ msgid "Exporting APK..."
msgstr "Eksporter"
#: platform/android/export/export_plugin.cpp
-#, fuzzy
msgid "Uninstalling..."
-msgstr "Avinstaller"
+msgstr "Avinstallerer …"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -14488,7 +14830,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14596,7 +14947,7 @@ msgstr "Genererer Lyskart"
#: scene/3d/baked_lightmap.cpp
msgid "Done"
-msgstr "Ferdig"
+msgstr "Fullført"
#: scene/3d/collision_object.cpp
msgid ""
@@ -14705,7 +15056,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
@@ -14951,11 +15310,11 @@ msgstr ""
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
-msgstr ""
+msgstr "RÃ¥"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
@@ -15023,7 +15382,7 @@ msgstr ""
#: scene/gui/tree.cpp
msgid "(Other)"
-msgstr ""
+msgstr "(Annet)"
#: scene/main/scene_tree.cpp
msgid ""
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 9574536fb7..f7f68d55f8 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -410,6 +410,7 @@ msgstr "Maak %d NIEUWE sporen aan en voer sleutels in?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -879,6 +880,7 @@ msgstr "Toevoegen"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -930,8 +932,7 @@ msgstr "Kan signaal niet verbinden"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1998,7 +1999,6 @@ msgid "New Folder..."
msgstr "Nieuwe map..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Verversen"
@@ -2115,7 +2115,8 @@ msgstr "Mappen & Bestanden:"
msgid "Preview:"
msgstr "Voorbeeld:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Bestand:"
@@ -2294,7 +2295,7 @@ msgstr "Methode"
msgid "Signal"
msgstr "Signaal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2325,6 +2326,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Zet %s"
@@ -3084,8 +3087,9 @@ msgid "Install Android Build Template..."
msgstr "Android Build-sjabloon Installeren ..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Projectdatamap openen"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Editordatamap openen"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3243,10 +3247,6 @@ msgid "Toggle Fullscreen"
msgstr "Volledig scherm"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Systeemconsole aan-/uitschakelen"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Editordata-/instellingenmap openen"
@@ -3483,6 +3483,7 @@ msgid "Load Errors"
msgstr "Laadfouten"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Selecteer"
@@ -3563,7 +3564,6 @@ msgid "Author"
msgstr "Auteurs"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3805,6 +3805,12 @@ msgstr "Scènepad:"
msgid "Import From Node:"
msgstr "Vanuit knoop importeren:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Fout"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4722,6 +4728,7 @@ msgid "Subfolder:"
msgstr "Submap:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Auteur:"
@@ -6435,6 +6442,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Voeg %s Toe"
@@ -9908,7 +9916,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Geen VCS addons beschikbaar."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9916,16 +9925,56 @@ msgid "Error"
msgstr "Fout"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Geen bestanden toegevoegd aan stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Geen naam opgegeven."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS Addon is niet geïnitialiseerd"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Shader Wijzigingen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Shader Wijzigingen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subtree"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Weet je zeker dat je meer dan één project wilt openen?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Reset"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9936,16 +9985,148 @@ msgid "Initialize"
msgstr "Initialiseren"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "staging gebied"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Punt verwijderen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Naam wijzigen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detecteer nieuwe veranderingen"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Wijzigingen"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Wijzigingen oplaan en sluiten?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Lokale wijziging aan het opslaan..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materiaal Wijzigingen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commit veranderingen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commit veranderingen"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Overeenkomsten:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Creëer Nieuw Project"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Verwijder Anim Track"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remote"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Creëer Nieuw Project"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Verwijder Item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remote "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remote "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Bron Mesh:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9964,30 +10145,23 @@ msgid "Typechange"
msgstr "Typewijziging"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Stage Geselecteerd"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Stage Alles"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commit veranderingen"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"Bekijk de veranderde bestanden voordat ze gebruikt worden in de nieuwste "
-"versie"
+#, fuzzy
+msgid "View:"
+msgstr "Weergeven"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Geen bestands veranderingen actief"
+#, fuzzy
+msgid "Split"
+msgstr "Splits Pad"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detecteer verandering in bestanden"
+#, fuzzy
+msgid "Unified"
+msgstr "Bewerkt"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12694,6 +12868,7 @@ msgid "Export list to a CSV file"
msgstr "Exporteer lijst naar een csv-bestand"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Bronpad"
@@ -13551,6 +13726,40 @@ msgstr "Diagram vernieuwen"
msgid "Edit Member"
msgstr "Lid bewerken"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Stel expressie in"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animatie"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Invoer type is niet iterabel: "
@@ -13563,6 +13772,88 @@ msgstr "Iterator werd ongeldig"
msgid "Iterator became invalid: "
msgstr "Iterator werd ongeldig: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Mapnaam wijzigen:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Pitch"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Type:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Zelf"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Bij teken %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Voeg %s Toe"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Zet %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Voeg %s Toe"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Krijg %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ongeldige index eigenschap naam."
@@ -13579,6 +13870,21 @@ msgstr "Pad leidt niet naar een knoop!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ongeldige eigenschapnaam '%s' in knoop %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Zet %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Functies"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Array Grootte Wijzigen"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Ongeldig argument van type: "
@@ -13588,6 +13894,10 @@ msgid ": Invalid arguments: "
msgstr ": Ongeldige argumenten: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet niet gevonden in script: "
@@ -13596,6 +13906,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet niet gevonden in script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Herladen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Schakel GDNative Singleton in"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek-knoop"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Scèneboombewerking"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Zelf"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Knopen knippen"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Zelfgemaakte knoop heeft geen _step() methode, kan diagram niet verwerken."
@@ -13608,13 +13978,75 @@ msgstr ""
"Ongeldige terugkeerwaarde van _step(), moet een geheel getal (sequentie "
"uitvoer) of string (fout) zijn."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Aanroepen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constanten"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Gebruik Lokale Ruimtemodus"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Gebruik Lokale Ruimtemodus"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Actie"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Zoek VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Krijg %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Verplaats Frame"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Physics Frame %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instantie"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14264,16 +14696,26 @@ msgstr ""
"ParallaxLayer-knoop werkt alleen als kind van een ParallaxBackground-knoop."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU-gebaseerde particles worden niet ondersteund door de GLES2-"
"stuurprogramma.\n"
"Gebruik in plaats daarvan een CPUParticles2D knoop. De \"Zet om in "
"CPUParticles\" optie kan hiervoor gebruikt worden."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14520,10 +14962,11 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Op GPU-gebaseerde particles worden niet ondersteund door het GLES2 grafische "
"stuurprogramma.\n"
@@ -14532,6 +14975,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Niets is zichtbaar want meshes zijn niet toegewezen aan de tekendoorlopen "
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 59c61de288..fb6c7ff0c2 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -355,6 +355,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -804,6 +805,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -853,8 +855,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1877,7 +1878,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1994,7 +1994,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2162,7 +2163,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2192,6 +2193,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2885,7 +2888,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3020,10 +3023,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3240,6 +3239,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3316,7 +3316,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3541,6 +3540,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4396,6 +4400,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6039,6 +6044,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9321,7 +9327,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9329,7 +9335,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9337,7 +9348,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9349,39 +9388,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9389,15 +9444,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11906,6 +12053,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12734,6 +12882,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12746,6 +12926,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12762,6 +13016,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12771,6 +13037,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12779,6 +13049,54 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12788,12 +13106,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13355,7 +13725,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13568,7 +13947,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index fd2468a30e..1f10b9f3a5 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -52,13 +52,14 @@
# Marek Malaria <to.tylko.dla.kont@gmail.com>, 2021.
# Mateusz Żak <matisgramy@gmail.com>, 2021.
# voltinus <voltinusmail@gmail.com>, 2021.
+# Lech Migdal <lech.migdal@gmail.com>, 2022.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-23 15:30+0000\n"
-"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
+"Last-Translator: Lech Migdal <lech.migdal@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
"Language: pl\n"
@@ -409,6 +410,7 @@ msgstr "Utworzyć %d NOWYCH ścieżek i dodać klatki kluczowe?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -876,6 +878,7 @@ msgstr "Dodaj"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -926,8 +929,7 @@ msgstr "Nie można połączyć sygnału"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1529,7 +1531,7 @@ msgstr "Niewłaściwa nazwa."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Nie może zaczynać się od cyfry."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1987,7 +1989,6 @@ msgid "New Folder..."
msgstr "Utwórz katalog..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Odśwież"
@@ -2104,7 +2105,8 @@ msgstr "Katalogi i pliki:"
msgid "Preview:"
msgstr "PodglÄ…d:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Plik:"
@@ -2152,9 +2154,8 @@ msgid "Properties"
msgstr "Właściwości"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "nadpisanie:"
+msgstr "nadpisuje %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2277,7 +2278,7 @@ msgstr "Metoda"
msgid "Signal"
msgstr "Sygnał"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Stała"
@@ -2308,6 +2309,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Ustaw %s"
@@ -3063,8 +3066,9 @@ msgid "Install Android Build Template..."
msgstr "Zainstaluj szablon eksportu dla Androida..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Otwórz folder danych projektu"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Otwórz folder danych edytora"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3221,10 +3225,6 @@ msgid "Toggle Fullscreen"
msgstr "Przełącz pełny ekran"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Przełącz systemową konsolę"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Otwórz folder ustawień/danych edytora"
@@ -3453,6 +3453,7 @@ msgid "Load Errors"
msgstr "Błędy wczytywania"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Zaznacz"
@@ -3529,7 +3530,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3773,6 +3773,12 @@ msgstr "Ścieżka sceny:"
msgid "Import From Node:"
msgstr "Zaimportuj z węzła:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Błąd"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Otwórz folder zawierający te szablony."
@@ -4662,6 +4668,7 @@ msgid "Subfolder:"
msgstr "Podfolder:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6362,6 +6369,7 @@ msgid "Zoom to 1600%"
msgstr "Przybliż do 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Dodaj %s"
@@ -9739,7 +9747,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Brak dostępnych dodatków VCS."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9747,16 +9756,56 @@ msgid "Error"
msgstr "Błąd"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Brak plików dodanych do stage'a"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nie podano nazwy."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Dodatek VCS nie jest zainicjowany"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Zmiany shadera:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Zmiany shadera:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Poddrzewo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Czy jesteś pewny że chcesz otworzyć więcej niż jeden projekt?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Zastosuj reset"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9767,16 +9816,148 @@ msgid "Initialize"
msgstr "Inicjuj"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Obszar stage'a"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Usuń punkt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Zmień nazwę"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Wykryj nowe zmiany"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Zmiany"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Zamknąć i zapisać zmiany?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Zachowywanie lokalnych zmian..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Zmiany materiału:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Commituj zmiany"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Commituj zmiany"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "PasujÄ…ce:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Utwórz nowy projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Usuń ścieżkę animacji"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Zdalny"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Utwórz nowy projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Usuń element"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Zdalny "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Zdalny "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Źródłowa siatka:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9795,28 +9976,23 @@ msgid "Typechange"
msgstr "Zmiana typu"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Stage'uj zaznaczone"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Stage'uj wszystko"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Commituj zmiany"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Zobacz różnice przed commitowaniem do najnowszej wersji"
+#, fuzzy
+msgid "View:"
+msgstr "Widok"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Brak aktywnego różnicowania plików (diff)"
+#, fuzzy
+msgid "Split"
+msgstr "Podziel Ścieżkę"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Wykryj zmiany w różnicach plików"
+#, fuzzy
+msgid "Unified"
+msgstr "Zmodyfikowany"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12507,6 +12683,7 @@ msgid "Export list to a CSV file"
msgstr "Eksportuj listÄ™ do pliku CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Ścieżka zasobu"
@@ -13352,6 +13529,40 @@ msgstr "Odśwież graf"
msgid "Edit Member"
msgstr "Edytuj członka"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Ustaw wyrażenie"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animacja"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Typ danych wejściowych nie jest iterowalny: "
@@ -13364,6 +13575,88 @@ msgstr "Iterator stał się nieprawidłowy"
msgid "Iterator became invalid: "
msgstr "Iterator stał się nieprawidłowy: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Zmiana nazwy folderu:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Pułap:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Typy:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Pojedynczo"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Przy znaku %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Dodaj %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Ustaw %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Dodaj %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Przyjmij %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nieprawidłowa nazwa właściwości indeksowej."
@@ -13380,6 +13673,21 @@ msgstr "Ścieżka nie prowadzi do węzła!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nieprawidłowy indeks we właściwości \"%s\" węzła %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Ustaw %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcje"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Zmień rozmiar Tablicy"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ":nieprawidłowy argument typu: "
@@ -13389,6 +13697,10 @@ msgid ": Invalid arguments: "
msgstr ":nieprawidłowe argumenty: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Nie znaleziono VariableGet w skrypcie: "
@@ -13397,6 +13709,66 @@ msgid "VariableSet not found in script: "
msgstr "Nie znaleziono VariableSet w skrypcie: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Przeładuj"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Indeks Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Indeks Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Stała"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Stała"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Stała"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Stała"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Włączony singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Węzeł Przewijania w Czasie"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edycja drzewa sceny"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Pojedynczo"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Wytnij węzły"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Niestandardowy węzeł nie posiada metody _step(), nie można przetworzyć grafu."
@@ -13409,13 +13781,75 @@ msgstr ""
"Nieprawidłowa wartość zwracana przez funkcję _step(), musi ona być liczbą "
"całkowitą (seq out), lub tekstową (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Wywołania"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Stałe"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Użyj przestrzeni lokalnej"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Użyj przestrzeni lokalnej"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Akcja"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Przeszukaj VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Przyjmij %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Przesuń klatkę"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Klatka fizyki %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sygnał"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sygnał"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instancja"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14061,15 +14495,25 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Cząsteczki oparte o GPU są nieobsługiwane przez sterownik wideo GLES2.\n"
"Użyj zamiast tego węzła CPUParticles2D. Możesz użyć do tego celu opcji "
"\"Konwertuj na CPUParticles\"."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14323,10 +14767,11 @@ msgid "Only uniform scales are supported."
msgstr "Obsługiwane są tylko jednolite skale."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Cząsteczki oparte o GPU są nieobsługiwane przez sterownik wideo GLES2.\n"
"Użyj zamiast tego węzła CPUParticles. Możesz użyć do tego celu opcji "
@@ -14334,6 +14779,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Nic nie jest widoczne, bo siatki nie zostały przypisane do kolejki rysowania."
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 799813904a..daa3074190 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -380,6 +380,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -841,6 +842,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -892,8 +894,7 @@ msgstr "Slit th' Node"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1951,7 +1952,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2070,7 +2070,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2244,7 +2245,7 @@ msgstr ""
msgid "Signal"
msgstr "Yer signals:"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2275,6 +2276,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2982,7 +2985,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "Slit th' Node"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3120,11 +3123,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Toggle ye Breakpoint"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3348,6 +3346,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3427,7 +3426,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3659,6 +3657,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Error loading yer Calligraphy Pen."
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4556,6 +4560,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6263,6 +6268,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9708,7 +9714,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9716,7 +9722,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9724,7 +9735,37 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Change"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Change"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9736,7 +9777,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Discharge ye' Signal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Rename Function"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9746,52 +9817,142 @@ msgstr "Yar, Blow th' Selected Down!"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
+msgid "Discard all changes"
msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr ""
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Rename Function"
+msgid "Unstage all changes"
+msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Slit th' Node"
+msgid "Commit Message"
+msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
+msgid "Commit Changes"
+msgstr "Change"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
+msgid "Create New Branch"
msgstr "Yar, Blow th' Selected Down!"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Rename Function"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
+msgid "Remotes"
+msgstr "Discharge ye' Signal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Discharge ye' Variable"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Discharge ye' Signal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Discharge ye' Signal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Rename Function"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Slit th' Node"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
msgstr "Change"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12374,6 +12535,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13268,6 +13430,40 @@ msgstr ""
msgid "Edit Member"
msgstr "th' Members:"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Swap yer Expression"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Yer functions:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Yar! Yer input aint iterable: "
@@ -13280,6 +13476,82 @@ msgstr "Yer Iterator be no good"
msgid "Iterator became invalid: "
msgstr "Yer Iterator be no good: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Switch"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "th' Base Type:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Yer index property name be thrown overboard!"
@@ -13296,6 +13568,19 @@ msgstr "There be no Node at ye path's end!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Yer index property name '%s' in node %s be walkin' th' plank!"
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Yer functions:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Evil argument of th' type: "
@@ -13305,6 +13590,10 @@ msgid ": Invalid arguments: "
msgstr ": Evil arguments: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet be in davy jones locker! Not in th' script: "
@@ -13313,6 +13602,60 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet be in davy jones locker! Not in th' script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Add yer Preload Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Slit th' Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Slit th' Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Yar, Blow th' Selected Down!"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Slit th' Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "Yer fancy node got no _step() method, we can't get th' graph."
@@ -13324,13 +13667,70 @@ msgstr ""
"Yer return value from _step() be no good! She must be th' integer (seq out) "
"or th' string (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Call"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Add Function"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Discharge ye' Variable"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Forge yer Node!"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Yer signals:"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Yer signals:"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13903,7 +14303,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14116,7 +14525,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/pt.po b/editor/translations/pt.po
index fcaec3fee6..443974d90c 100644
--- a/editor/translations/pt.po
+++ b/editor/translations/pt.po
@@ -6,7 +6,7 @@
# Carlos Vieira <carlos.vieira@gmail.com>, 2017.
# João <joao@nogordio.com>, 2018.
# João Graça <jgraca95@gmail.com>, 2017.
-# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021.
+# João Lopes <linux-man@hotmail.com>, 2017-2018, 2019, 2020, 2021, 2022.
# Miguel Gomes <miggas09@gmail.com>, 2017.
# Paulo Caldeira <paucal@gmail.com>, 2018.
# Pedro Gomes <pedrogomes1698@gmail.com>, 2017.
@@ -24,7 +24,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-31 08:52+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
"Language-Team: Portuguese <https://hosted.weblate.org/projects/godot-engine/"
"godot/pt/>\n"
@@ -336,9 +336,8 @@ msgid "Duplicate Key(s)"
msgstr "Duplicar Chave(s)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "Adicionar %d Frame(s)"
+msgstr "Adicionar Valor(es) RESET"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -375,6 +374,7 @@ msgstr "Criar %d NOVAS pistas e inserir chaves?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -510,9 +510,8 @@ msgstr ""
"Esta opção não funciona para edição de Bezier, dado que é uma única faixa."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "Anim Escalar Chaves"
+msgstr "Anim Adicionar Chaves RESET"
#: editor/animation_track_editor.cpp
msgid ""
@@ -843,6 +842,7 @@ msgstr "Adicionar"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -894,8 +894,7 @@ msgstr "Incapaz de conectar sinal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1500,7 +1499,7 @@ msgstr "Nome inválido."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Não pode começar com um dígito."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1960,7 +1959,6 @@ msgid "New Folder..."
msgstr "Nova Diretoria..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Atualizar"
@@ -2077,7 +2075,8 @@ msgstr "Diretorias e Ficheiros:"
msgid "Preview:"
msgstr "Pré-visualização:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Ficheiro:"
@@ -2127,9 +2126,8 @@ msgid "Properties"
msgstr "Propriedades"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "sobrepor:"
+msgstr "sobrepor %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2252,7 +2250,7 @@ msgstr "Método"
msgid "Signal"
msgstr "Sinal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2269,20 +2267,22 @@ msgid "Property:"
msgstr "Propriedade:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(valor)"
+msgstr "Valor pin"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"Fixar um valor força-o a ser guardado mesmo que seja igual à predefinição."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
-msgstr ""
+msgstr "Fixar valor [Desativado porque '%s' é só-para-editor]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Definir %s"
@@ -2293,26 +2293,23 @@ msgstr "Definir Múltiplo:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Fixado %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "Desafixado %s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Copiar Propriedades"
+msgstr "Copiar Propriedade"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Colar Propriedades"
+msgstr "Colar Propriedade"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Copiar Caminho do Script"
+msgstr "Copiar Caminho da Propriedade"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3040,8 +3037,9 @@ msgid "Install Android Build Template..."
msgstr "Instalar Modelo Android de Compilação..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Abrir Pasta de Dados do Projeto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Abrir Pasta de Dados do Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3129,7 +3127,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "Forçar Shader de Recurso"
#: editor/editor_node.cpp
msgid ""
@@ -3199,10 +3197,6 @@ msgid "Toggle Fullscreen"
msgstr "Alternar Ecrã completo"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Alternar Consola do Sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Abrir Pasta do Editor de Dados/Configurações"
@@ -3432,6 +3426,7 @@ msgid "Load Errors"
msgstr "Carregar Erros"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Selecionar"
@@ -3508,7 +3503,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3753,6 +3747,12 @@ msgstr "Caminho da Cena:"
msgid "Import From Node:"
msgstr "Importar do Nó:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Erro"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Abrir a pasta que contem estes modelos."
@@ -4298,9 +4298,8 @@ msgid "Replace..."
msgstr "Substituir..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Substituir todos"
+msgstr "Substituir em Ficheiros"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4311,9 +4310,8 @@ msgid "Replace: "
msgstr "Substituir: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Substituir todos"
+msgstr "Substituir Tudo (DEFINITIVO)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4537,6 +4535,8 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Selecione um ficheiro de recurso no sistema de ficheiros ou no inspetor para "
+"ajustar configuração de importação."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4645,6 +4645,7 @@ msgid "Subfolder:"
msgstr "Sub-pasta:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -5997,9 +5998,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt+Arrastar: Mover nó selecionado."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+Arrastar: Mover nó selecionado."
+msgstr "Alt+Arrastar: Escalar nó selecionado."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6033,7 +6033,7 @@ msgstr "Modo Escalar"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Shift: Escalar proporcionalmente."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6132,9 +6132,8 @@ msgstr "Bloquear a posição do objeto selecionado (não pode ser movido)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Bloquear Seleção"
+msgstr "Bloquear Nó(s) Selecionado(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6143,9 +6142,8 @@ msgstr "Desbloquear o Objeto selecionado (pode ser movido)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Desbloquear Seleção"
+msgstr "Desbloquear Nó(s) Selecionado(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6154,9 +6152,8 @@ msgstr "Assegura que os Objetos-filho não são selecionáveis."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Agrupar Seleção"
+msgstr "Agrupar Nó(s) Selecionado(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6165,9 +6162,8 @@ msgstr "Restaura a capacidade de selecionar os Objetos-filho."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Desagrupar Seleção"
+msgstr "Desagrupar Nó(s) Selecionado(s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6340,6 +6336,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom a 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Adicionar %s"
@@ -7806,9 +7803,8 @@ msgid "Find in Files..."
msgstr "Localizar em Ficheiros..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Substituir..."
+msgstr "Substituir em Ficheiros..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -8336,16 +8332,15 @@ msgstr "Alternar Freelook"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "Reduzir Campo de Visão"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "Aumentar Campo de Visão"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "Restaurar Predefinição"
+msgstr "Restaurar Campo de Visão para Predefinição"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9074,22 +9069,19 @@ msgstr "Adicionar Tipo"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "Filtra a lista de tipos ou cria um novo tipo personalizado:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "Perfis disponíveis:"
+msgstr "Tipos de Nós disponíveis:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "Nome do Ficheiro vazio."
+msgstr "Nome do tipo vazio!"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Está seguro que quer abrir mais do que um Projeto?"
+msgstr "Está seguro que quer criar um tipo vazio?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9709,7 +9701,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Não existem addons VCS disponíveis."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9717,16 +9710,56 @@ msgid "Error"
msgstr "Erro"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Nenhum ficheiro adicionado ao palco"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nome não fornecido."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Gravar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Addon VCS não foi inicializado"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Mudanças do Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Mudanças do Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Gravar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Sub-árvore"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Está seguro que quer criar um tipo vazio?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Aplicar Reinicialização"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9737,16 +9770,148 @@ msgid "Initialize"
msgstr "Inicializar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Ãrea de Palco"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Remover Ponto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renomear"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detetar novas alterações"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Alterações"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Fechar e guardar alterações?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "A armazenar alterações locais..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Mudanças de Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Gravar Alterações"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Gravar Alterações"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Gravar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Correspondências:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Criar novo Projeto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Remover Pista de Animação"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Criar novo Projeto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Remover item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Fonte Malha:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9765,28 +9930,23 @@ msgid "Typechange"
msgstr "Mudança de tipo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Palco Selecionado"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Tudo no Palco"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Gravar Alterações"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Ver diffs dos ficheiros antes de atualizá-los para a última versão"
+#, fuzzy
+msgid "View:"
+msgstr "Vista"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Nenhum ficheiro diff está ativo"
+#, fuzzy
+msgid "Split"
+msgstr "Separar Caminho"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detetar alterações em ficheiro diff"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificado"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12474,6 +12634,7 @@ msgid "Export list to a CSV file"
msgstr "Exportar lista para ficheiro CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Caminho do Recurso"
@@ -13319,6 +13480,40 @@ msgstr "Atualizar Gráfico"
msgid "Edit Member"
msgstr "Editar Membro"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Definir expressão"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animação"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tipo de Input não iterável: "
@@ -13331,6 +13526,88 @@ msgstr "O iterador tornou-se inválido"
msgid "Iterator became invalid: "
msgstr "O iterador tornou-se inválido: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renomear diretoria:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Inclinação:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Tipos:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Auto"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "No carácter %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Adicionar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Definir %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Fixado %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Obter %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nome de índice Propriedade inválido."
@@ -13347,6 +13624,21 @@ msgstr "Caminho não conduz Nó!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nome de propriedade índice '%s' inválido no nó %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Definir %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funções"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionar Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argumento inválido de tipo: "
@@ -13356,6 +13648,10 @@ msgid ": Invalid arguments: "
msgstr ": Argumentos inválidos: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet não encontrado no script: "
@@ -13364,6 +13660,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet não encontrado no script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Recarregar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Ativa Singleton GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nó TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edição da Ãrvore de Cena"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Auto"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Cortar Nós"
+
+#: 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(), sem poder processar um gráfico."
@@ -13376,13 +13732,75 @@ msgstr ""
"Retorno de valor inválido a partir do _step(), tem de ser inteiro (seq out), "
"ou cadeia (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Chamadas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usar Espaço Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usar Espaço Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Ação"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Procurar VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Obter %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mover Frame"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Frame de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instância"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13994,7 +14412,7 @@ msgstr "O polígono oclusor deste oclusor está vazio. Desenhe um polígono."
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
-msgstr ""
+msgstr "O NavigationAgent2D pode ser apenas usado dentro de um nó Node2D."
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
@@ -14026,15 +14444,25 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Partículas baseadas em GPU não são suportadas pelo driver de vídeo GLES2.\n"
"Use o nó CPUParticles2D. Pode usar a opção \"Converter em CPUParticles\" "
"para este efeito."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14283,10 +14711,11 @@ msgid "Only uniform scales are supported."
msgstr "Apenas são suportadas escalas uniformes."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Partículas baseadas em GPU não são suportadas pelo driver de vídeo GLES2.\n"
"Use o nó CPUParticles. Pode usar a opção \"Converter em CPUParticles\" para "
@@ -14294,6 +14723,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Nada é visível porque não foram atribuídas malhas aos passos de desenho."
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index f4872c4483..b60b09c80e 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -488,6 +488,7 @@ msgstr "Criar %d NOVAS faixas e inserir chaves?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -957,6 +958,7 @@ msgstr "Adicionar"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -1007,8 +1009,7 @@ msgstr "Não foi possível conectar o sinal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2073,7 +2074,6 @@ msgid "New Folder..."
msgstr "Nova Pasta..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Atualizar"
@@ -2190,7 +2190,8 @@ msgstr "Diretórios & Arquivos:"
msgid "Preview:"
msgstr "Previsualização:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Arquivo:"
@@ -2365,7 +2366,7 @@ msgstr "Método"
msgid "Signal"
msgstr "Sinal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constante"
@@ -2396,6 +2397,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Conjunto %s"
@@ -3158,8 +3161,9 @@ msgid "Install Android Build Template..."
msgstr "Instalar Modelo de Compilação Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Abrir Pasta do Projeto"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Abrir a Pasta de dados do Editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3317,10 +3321,6 @@ msgid "Toggle Fullscreen"
msgstr "Alternar Tela Cheia"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Alternar Console do Sistema"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Abrir Editor/Configurações de Pasta"
@@ -3551,6 +3551,7 @@ msgid "Load Errors"
msgstr "Erros de Carregamento"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Selecionar"
@@ -3627,7 +3628,6 @@ msgid "Author"
msgstr "Autor"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Estado"
@@ -3873,6 +3873,12 @@ msgstr "Caminho da Cena:"
msgid "Import From Node:"
msgstr "Importar a Partir do Nó:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Erro"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Abrir a pasta contendo esses modelos."
@@ -4771,6 +4777,7 @@ msgid "Subfolder:"
msgstr "Subpasta:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6475,6 +6482,7 @@ msgid "Zoom to 1600%"
msgstr "Zoom para 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Adicionar %s"
@@ -9849,7 +9857,8 @@ msgid "TileSet"
msgstr "Conjunto de Telha"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Nenhum complemento VCS está disponível."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9857,16 +9866,56 @@ msgid "Error"
msgstr "Erro"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Nenhum arquivo em espera"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nenhum nome fornecido."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Confirmação"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS Addon não inicializado"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Alterações de Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Alterações de Shader:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Confirmação"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Subárvore"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Tem certeza de que quer abrir mais de um projeto?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Redefinir"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9877,16 +9926,148 @@ msgid "Initialize"
msgstr "Inicializar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Ãrea de espera"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Remover Ponto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Renomear"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Detectar novas mudanças"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Mudanças"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Fechar e salvar alterações?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Armazenando alterações locais..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Alterações de Material:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Confirmar Mudanças"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Confirmar Mudanças"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Confirmação"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Correspondências:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Criar Novo Projeto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Remover Trilha da Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Remoto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Criar Novo Projeto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Remover Item"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Remoto "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Malha de Origem:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9905,28 +10086,23 @@ msgid "Typechange"
msgstr "Alteração de tipo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Estágio selecionado"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Salvar Tudo"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Confirmar Mudanças"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Ver aquivos diff antes do commit para a última versão"
+#, fuzzy
+msgid "View:"
+msgstr "Visualizar"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Nenhuma mudança no arquivo"
+#, fuzzy
+msgid "Split"
+msgstr "Dividir Caminho"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Detectar mudanças no arquivo diff"
+#, fuzzy
+msgid "Unified"
+msgstr "Modificado"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12619,6 +12795,7 @@ msgid "Export list to a CSV file"
msgstr "Exportar lista para arquivo CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Caminho do Recurso"
@@ -13465,6 +13642,40 @@ msgstr "Atualizar Grafo"
msgid "Edit Member"
msgstr "Editar Membro"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Definir expressão"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animação"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Tipo de entrada não iterável: "
@@ -13477,6 +13688,88 @@ msgstr "Iterador tornou-se inválido"
msgid "Iterator became invalid: "
msgstr "Iterador tornou-se inválido: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Renomear pasta:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Tom:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Modelos:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Self"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Para caractere %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Adicionar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Conjunto %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Adicionar %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Receba %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Nome da propriedade de índice inválido."
@@ -13493,6 +13786,21 @@ msgstr "Caminho não leva a um Nó!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Nome de propriedade '%s' inválido no nó %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Conjunto %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funções"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionar Vetor"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Argumento inválido do tipo: "
@@ -13502,6 +13810,10 @@ msgid ": Invalid arguments: "
msgstr ": Argumentos inválidos: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet não encontrada no script: "
@@ -13510,6 +13822,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet não encontrada no script: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Recarregar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Ãndice Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Singleton GDNative ativado"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nó TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Edição da Ãrvore de Cena"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Self"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Recortar Nós"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"Nó customizado não tem um método _step(), não foi possível processar o "
@@ -13523,13 +13895,75 @@ msgstr ""
"Valor de retorno da _step() inválido, deve ser um inteiro (seq out), ou "
"string (erro)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Chamadas"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constantes"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Usar Espaço Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Usar Espaço Local"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Ação"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Buscar VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Receba %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mover Quadro"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Frame de Física %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instância"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14180,15 +14614,25 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Partículas baseadas em GPU não são suportadas pelo driver de vídeo GLES2.\n"
"Use o nó CPUParticles2D como substituto. Você pode usar a opção \"Converter "
"para CPUParticles\" para este propósito."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14441,10 +14885,11 @@ msgid "Only uniform scales are supported."
msgstr "Apenas escalas uniformes são suportadas."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"Partículas baseadas em GPU não são suportadas pelo driver de vídeo GLES2.\n"
"Use o nó CPUParticles como substituto. Você pode usar a opção \"Converter "
@@ -14452,6 +14897,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Nada está visível porque as meshes não foram atribuídas a passes de desenho."
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index d763d64a8c..216de7fab1 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -374,6 +374,7 @@ msgstr "Creați %d piste NOI și inserați cheie?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -842,6 +843,7 @@ msgstr "Adăugați"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -892,8 +894,7 @@ msgstr "Nu se poate conecta semnalul"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1967,7 +1968,6 @@ msgid "New Folder..."
msgstr "Director Nou..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Reîmprospătare"
@@ -2084,7 +2084,8 @@ msgstr "Directoare și Fişiere:"
msgid "Preview:"
msgstr "Previzualizați:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fișier:"
@@ -2260,7 +2261,7 @@ msgstr "Metodă"
msgid "Signal"
msgstr "Semnal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Permanent"
@@ -2291,6 +2292,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Set %s"
@@ -3046,8 +3049,9 @@ msgid "Install Android Build Template..."
msgstr "Instalare șablon compilare Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Deschideți folderul datelor proiectului"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Deschidere dosarul de date editor"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3207,10 +3211,6 @@ msgid "Toggle Fullscreen"
msgstr "Comutare ecran complet"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Cumutează Consola de Sistem"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Deschide Dosarul De Date/Setări"
@@ -3436,6 +3436,7 @@ msgid "Load Errors"
msgstr "Încarcă Erorile"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Selectează"
@@ -3516,7 +3517,6 @@ msgid "Author"
msgstr "Autori"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3748,6 +3748,12 @@ msgstr "Calea Scenei:"
msgid "Import From Node:"
msgstr "Importă Din Nod:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Eroare!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4649,6 +4655,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6419,6 +6426,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Adaugă %s"
@@ -9950,7 +9958,7 @@ msgid "TileSet"
msgstr "Set de dale"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9958,19 +9966,58 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Niciun nume furnizat."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Comunitate"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Schimbați"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Schimbați"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Comunitate"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Ești sigur că vrei să ștergi toate conexiunile de la acest semnal?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Resetați"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9979,7 +10026,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Elimină punct"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Redenumește"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9989,53 +10066,146 @@ msgstr "Creați %s Nou"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Schimbați"
+msgid "Discard all changes"
+msgstr "Modificări ale Actualizării"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Modificările locale se stochează..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Modificări ale Actualizării"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Sincronizează Modificările Scriptului"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Sincronizează Modificările Scriptului"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Comunitate"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Redenumește"
+msgid "Branches"
+msgstr "Potriviri:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
+msgid "Create New Branch"
+msgstr "Creați %s Nou"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Elimină Pista Anim"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
msgstr "Ștergeți"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Schimbați"
+msgid "Create New Remote"
+msgstr "Creați %s Nou"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Scalați Selecția"
+msgid "Remove Remote"
+msgstr "Elimină Șablon"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Înlocuiți Tot"
+msgid "Remote Name"
+msgstr "Nume Nod:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Sincronizează Modificările Scriptului"
+msgid "Remote URL"
+msgstr "Ștergeți"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Mesh Sursă:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Redenumește"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Ștergeți"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Schimbați"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Perspectivă"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Divizare cale"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12632,6 +12802,7 @@ msgid "Export list to a CSV file"
msgstr "Exportă Profil"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13500,6 +13671,40 @@ msgstr "Reîmprospătați"
msgid "Edit Member"
msgstr "Membri"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Setare expresie"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animație"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13512,6 +13717,86 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Redenumind directorul:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Propriu"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "La caracterul %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Adaugă %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Setați %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Adaugă %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13528,6 +13813,21 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Setați %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funcții"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Redimensionați Array-ul"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13537,6 +13837,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13545,6 +13849,64 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Mod ÃŽn Jur"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Mod ÃŽn Jur"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Permanent"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Permanent"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Permanent"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Permanent"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nod CăutareTimp"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Editează Arborele Scenei"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Propriu"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Creează Nod"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13554,15 +13916,77 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Apeluri"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Constante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Creează Oase"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Creează Oase"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Acțiune"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Curăță Scriptul"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Mod Mutare"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Cadru Fizic %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Semnal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Semnal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instanță"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14148,7 +14572,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14363,7 +14796,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index dfecd99550..d8ca320413 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -56,7 +56,7 @@
# КонÑтантин Рин <email.to.rean@gmail.com>, 2019, 2020.
# Maxim Samburskiy <alpacones@outlook.com>, 2019.
# Dima Koshel <form.eater@gmail.com>, 2019.
-# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021.
+# Danil Alexeev <danil@alexeev.xyz>, 2019, 2020, 2021, 2022.
# Ravager <al.porkhunov@gmail.com>, 2019.
# ÐлекÑандр <akonn7@mail.ru>, 2019.
# Rei <clxgamer12@gmail.com>, 2019.
@@ -106,7 +106,7 @@ msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-14 15:28+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
@@ -116,7 +116,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.10-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -421,9 +421,8 @@ msgid "Duplicate Key(s)"
msgstr "Дублировать ключ(и)"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "Добавить кадров: %d"
+msgstr "Добавить значение(Ñ) СБРОСа"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -460,6 +459,7 @@ msgstr "Создать %d новые дорожки и вÑтавить ключ
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -595,9 +595,8 @@ msgstr ""
"одна дорожка."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "МаÑштабировать ключи"
+msgstr "Добавить ключи СБРОСа"
#: editor/animation_track_editor.cpp
msgid ""
@@ -928,6 +927,7 @@ msgstr "Добавить"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -979,8 +979,7 @@ msgstr "Ðе удаетÑÑ Ð¿Ñ€Ð¸Ñоединить Ñигнал"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1581,7 +1580,7 @@ msgstr "ÐедопуÑтимое имÑ."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Ðе может начинатьÑÑ Ñ Ñ†Ð¸Ñ„Ñ€Ñ‹."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -2044,7 +2043,6 @@ msgid "New Folder..."
msgstr "ÐÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Обновить"
@@ -2161,7 +2159,8 @@ msgstr "Каталоги и файлы:"
msgid "Preview:"
msgstr "ПредпроÑмотр:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Файл:"
@@ -2211,9 +2210,8 @@ msgid "Properties"
msgstr "СвойÑтва"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "переопределено:"
+msgstr "переопределÑет %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2336,7 +2334,7 @@ msgstr "Метод"
msgid "Signal"
msgstr "Сигнал"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "КонÑтанта"
@@ -2353,20 +2351,24 @@ msgid "Property:"
msgstr "Параметр:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(значение)"
+msgstr "Закрепить значение"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"Закрепление Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð·Ð°ÑтавлÑет его ÑохранÑтьÑÑ, даже еÑли оно равно "
+"значению по умолчанию."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
+"Закрепить значение [Отключено, так как «%s» доÑтупно только Ð´Ð»Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¾Ñ€Ð°]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Задать %s"
@@ -2377,26 +2379,23 @@ msgstr "Задать неÑколько:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Закреплено %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "Откреплено %s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Копировать ÑвойÑтва"
+msgstr "Копировать ÑвойÑтво"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Ð’Ñтавить ÑвойÑтва"
+msgstr "Ð’Ñтавить ÑвойÑтво"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Копировать путь к Ñкрипту"
+msgstr "Копировать путь к ÑвойÑтву"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3125,8 +3124,9 @@ msgid "Install Android Build Template..."
msgstr "УÑтановить шаблон Ñборки Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Открыть папку Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ проекта"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Открыть папку данных редактора"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3214,7 +3214,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "Принудительно уÑтановить резервные шейдеры"
#: editor/editor_node.cpp
msgid ""
@@ -3225,6 +3225,13 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"ЕÑли Ñта Ð¾Ð¿Ñ†Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°, шейдеры будут иÑпользоватьÑÑ Ð² их резервной форме "
+"(либо видимой через убершейдер, либо Ñкрытой) в течение вÑего времени "
+"выполнениÑ.\n"
+"Это полезно Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ внешнего вида и производительноÑти резервных "
+"шейдеров, которые обычно отображаютÑÑ Ð½Ð° короткое времÑ.\n"
+"ÐÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¸Ð»ÑÑ†Ð¸Ñ ÑˆÐµÐ¹Ð´ÐµÑ€Ð¾Ð² должна быть включена в наÑтройках проекта, "
+"чтобы Ñтот параметр имел значение."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3283,10 +3290,6 @@ msgid "Toggle Fullscreen"
msgstr "Включить полноÑкранный режим"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Переключить ÑиÑтемную конÑоль"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Открыть папку данных/наÑтроек редактора"
@@ -3518,6 +3521,7 @@ msgid "Load Errors"
msgstr "Ошибки загрузки"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Выделение"
@@ -3594,7 +3598,6 @@ msgid "Author"
msgstr "Ðвтор"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "СтатуÑ"
@@ -3838,6 +3841,12 @@ msgstr "Путь к Ñцене:"
msgid "Import From Node:"
msgstr "Импортировать из узла:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Ошибка"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Открыть папку, Ñодержащую Ñти шаблоны."
@@ -4379,9 +4388,8 @@ msgid "Replace..."
msgstr "Заменить..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Заменить вÑÑ‘"
+msgstr "Заменить в файлах"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4392,9 +4400,8 @@ msgid "Replace: "
msgstr "Заменить: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Заменить вÑÑ‘"
+msgstr "Заменить вÑÑ‘ (ÐЕЛЬЗЯ ОТМЕÐИТЬ)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4619,6 +4626,8 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Выберите файл реÑурÑа в файловой ÑиÑтеме или в инÑпекторе, чтобы наÑтроить "
+"параметры импорта."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4727,6 +4736,7 @@ msgid "Subfolder:"
msgstr "Подпапка:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Ðвтор:"
@@ -6076,12 +6086,11 @@ msgstr "Тащить: Вращать выделенный узел вокруг
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move selected node."
-msgstr "Alt+Тащить: перемещение выбранного узла."
+msgstr "Alt+Тащить: Перемещение выбранного узла."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+Тащить: перемещение выбранного узла."
+msgstr "Alt+Тащить: МаÑштабирование выбранного узла."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6115,7 +6124,7 @@ msgstr "Режим маÑштабированиÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Shift: МаÑштабировать пропорционально."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6210,13 +6219,12 @@ msgstr "ПривÑзка к направлÑющим"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock the selected object in place (can't be moved)."
-msgstr "ЗафикÑировать выбранный объект."
+msgstr "Заблокировать выбранный объект."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Заблокировать выбранное"
+msgstr "Заблокировать выбранный узел(узлы)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6225,9 +6233,8 @@ msgstr "Разблокировать выбранный объект."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Разблокировать выделенное"
+msgstr "Разблокировать выбранный узел(узлы)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6236,9 +6243,8 @@ msgstr "Делает потомков объекта невыбираемыми.
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Сгруппировать выделенное"
+msgstr "Сгруппировать выбранный узел(узлы)"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6247,9 +6253,8 @@ msgstr "ВоÑÑтанавливает возможноÑть выбора поÑ
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Разгруппировать выделенное"
+msgstr "Разгруппировать выбранный узел(узлы)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6422,6 +6427,7 @@ msgid "Zoom to 1600%"
msgstr "МаÑштаб 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Добавить %s"
@@ -7893,9 +7899,8 @@ msgid "Find in Files..."
msgstr "Ðайти в файлах..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Заменить..."
+msgstr "Заменить в файлах..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -8424,16 +8429,15 @@ msgstr "Включить Ñвободный вид"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "Уменьшить поле зрениÑ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "Увеличить поле зрениÑ"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "СброÑить наÑтройки"
+msgstr "СброÑить поле Ð·Ñ€ÐµÐ½Ð¸Ñ Ðº значению по умолчанию"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9164,22 +9168,19 @@ msgstr "Добавить тип"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "Отфильтровать ÑпиÑок типов или Ñоздать новый пользовательÑкий тип:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "ДоÑтупные профили:"
+msgstr "ДоÑтупные типы на оÑнове Node:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "ПуÑтое Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°."
+msgstr "Ð˜Ð¼Ñ Ñ‚Ð¸Ð¿Ð° пуÑто!"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Вы уверены, что хотите открыть более одного проекта?"
+msgstr "Ð’Ñ‹ уверены, что хотите Ñоздать пуÑтой тип?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9802,7 +9803,8 @@ msgid "TileSet"
msgstr "Ðабор тайлов"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Ðет доÑтупных VCS плагинов."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9810,16 +9812,56 @@ msgid "Error"
msgstr "Ошибка"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Ðе добавлены файлы Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¼Ð¸Ñ‚Ð°"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Ðе предоÑтавлено имÑ."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Коммит"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Плагин VCS не инициализирован"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Шейдеров изменено:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Шейдеров изменено:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Коммит"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Поддерево"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Ð’Ñ‹ уверены, что хотите Ñоздать пуÑтой тип?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Применить ÑброÑ"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9830,16 +9872,148 @@ msgid "Initialize"
msgstr "Инициализировать"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "ОблаÑть коммита"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Удалить точку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Переименовать"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Проверить изменениÑ"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "ИзменениÑ"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Закрыть и Ñохранить изменениÑ?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Сохранение локальных изменений..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Материалов изменено:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Закоммитить изменениÑ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Закоммитить изменениÑ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Коммит"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "СовпадениÑ:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Создать новый проект"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Удалить дорожку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Удаленный"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Создать новый проект"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Удалить Ñлемент"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Удаленный "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Удаленный "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð¾Ð»Ð¸Ñетка:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9858,28 +10032,23 @@ msgid "Typechange"
msgstr "Изменить тип"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "ИндекÑ. выбранные"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "ИндекÑ. вÑÑ‘"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Закоммитить изменениÑ"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "ПроÑмотр различий в файлах перед коммитом"
+#, fuzzy
+msgid "View:"
+msgstr "Вид"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Ðет выбранных изменений"
+#, fuzzy
+msgid "Split"
+msgstr "Разделить путь"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Обнаружение изменений в разнице в файлах"
+#, fuzzy
+msgid "Unified"
+msgstr "Изменён"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12028,6 +12197,11 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ðевозможно Ñохранить ветку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑвлÑетÑÑ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ð¼ Ñлементом уже "
+"инÑтанцированной Ñцены.\n"
+"Чтобы Ñохранить Ñту ветку в отдельной Ñцене, откройте иÑходную Ñцену, "
+"щёлкните правой кнопкой мыши по Ñтой ветке и выберите «Сохранить ветку как "
+"Ñцену»."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -12035,6 +12209,10 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ðевозможно Ñохранить ветку, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÑвлÑетÑÑ Ñ‡Ð°Ñтью унаÑледованной Ñцены.\n"
+"Чтобы Ñохранить Ñту ветку в отдельной Ñцене, откройте иÑходную Ñцену, "
+"щёлкните правой кнопкой мыши по Ñтой ветке и выберите «Сохранить ветку как "
+"Ñцену»."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -12576,6 +12754,7 @@ msgid "Export list to a CSV file"
msgstr "ЭкÑпортировать профиль в CSV файл"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Путь к реÑурÑу"
@@ -13421,6 +13600,40 @@ msgstr "Обновить график"
msgid "Edit Member"
msgstr "Редактировать Ñлемент"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Задать выражение"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "анимациÑ"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Входной тип не итерируемый: "
@@ -13433,6 +13646,88 @@ msgstr "Итератор Ñтал недейÑтвительным"
msgid "Iterator became invalid: "
msgstr "Итератор Ñтал недейÑтвительным: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Переименование папки:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Ð’Ñ‹Ñота:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Типы:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Субъект"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Ðа Ñимволе %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Добавить %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Задать %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Закреплено %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Получить %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ðеверный Ð¸Ð½Ð´ÐµÐºÑ ÑвойÑтва имени."
@@ -13449,6 +13744,21 @@ msgstr "Путь не приводит к узлу!"
msgid "Invalid index property name '%s' in node %s."
msgstr "ÐедопуÑтимое Ð¸Ð¼Ñ ÑвойÑтва-индекÑа «%s» в узле %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Задать %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Функции"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Изменить размер маÑÑива"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": ÐедопуÑтимый аргумент типа: "
@@ -13458,6 +13768,10 @@ msgid ": Invalid arguments: "
msgstr ": ÐедопуÑтимые аргументы: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet не найден в Ñкрипте: "
@@ -13466,6 +13780,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet не найден в Ñкрипте: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Перезагрузить"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z-индекÑ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z-индекÑ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "КонÑтанта"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Включён GDNative Ñинглтон"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek узел"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Редактирование дерева Ñцены"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Субъект"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Вырезать узлы"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
"ПользовательÑкий узел не имеет метода _step(), не возможно обрабатывать граф."
@@ -13478,13 +13852,75 @@ msgstr ""
"ÐедопуÑтимое значение, возвращаемое _step(), должно быть целое чиÑло(seq "
"out) или Ñтрока (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Вызовы"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "КонÑтанты"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "ИÑпользовать локальное проÑтранÑтво"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "ИÑпользовать локальное проÑтранÑтво"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ДейÑтвие"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "ИÑкать VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Получить %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "ПеремеÑтить кадр"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Кадр физики %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Добавить ÑкземплÑÑ€"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14089,13 +14525,15 @@ msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
-msgstr ""
+msgstr "NavigationAgent2D можно иÑпользовать только под узлом Node2D."
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
"The NavigationObstacle2D only serves to provide collision avoidance to a "
"Node2D object."
msgstr ""
+"NavigationObstacle2D Ñлужит только Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ñтолкновений Ñ "
+"объектом Node2D."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -14121,15 +14559,25 @@ msgstr ""
"узла ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU-чаÑтицы не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n"
"ВмеÑто Ñтого иÑпользуйте узел CPUParticles2D. Ð”Ð»Ñ Ñтого можно "
"воÑпользоватьÑÑ Ð¾Ð¿Ñ†Ð¸ÐµÐ¹ «Преобразовать в CPUParticles»."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14358,7 +14806,7 @@ msgstr "SpotLight Ñ ÑƒÐ³Ð»Ð¾Ð¼ более 90 градуÑов не может Ð
#: scene/3d/navigation_agent.cpp
msgid "The NavigationAgent can be used only under a spatial node."
-msgstr ""
+msgstr "NavigationAgent можно иÑпользовать только под узлом Spatial."
#: scene/3d/navigation_mesh_instance.cpp
msgid ""
@@ -14373,6 +14821,8 @@ msgid ""
"The NavigationObstacle only serves to provide collision avoidance to a "
"spatial object."
msgstr ""
+"NavigationObstacle Ñлужит только Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ñтолкновений Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð¼ "
+"Spatial."
#: scene/3d/occluder.cpp
msgid "No shape is set."
@@ -14383,10 +14833,11 @@ msgid "Only uniform scales are supported."
msgstr "ПоддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ маÑштабирование uniform."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPU-чаÑтицы не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n"
"ВмеÑто Ñтого иÑпользуйте узел CPUParticles. Ð”Ð»Ñ Ñтого можно воÑпользоватьÑÑ "
@@ -14394,6 +14845,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "Ðичего не видно, потому что полиÑетки не были назначены на отриÑовку."
diff --git a/editor/translations/si.po b/editor/translations/si.po
index c1b97c5ebf..f3802b7346 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -368,6 +368,7 @@ msgstr "%d සදහ෠ලුහුබදින්නන් à·ƒà·à¶¯à· යත
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -829,6 +830,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -879,8 +881,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1907,7 +1908,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2024,7 +2024,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2192,7 +2193,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2223,6 +2224,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2920,7 +2923,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3055,10 +3058,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3277,6 +3276,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3353,7 +3353,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3579,6 +3578,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "à¶šà·à¶©à¶´à¶­"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4438,6 +4443,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6108,6 +6114,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9421,7 +9428,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9429,7 +9436,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9437,7 +9449,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9449,7 +9489,36 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "මෙම ලුහුබදින්න෠ඉවත් කරන්න."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Username"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9457,49 +9526,133 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "යතුරු මක෠දමන්න"
+msgid "Create New Branch"
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Anim ලුහුබදින්න෠ඉවත් කරන්න"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "à¶­à·à¶»à·à¶œà¶­à·Š යතුරු මක෠දමන්න"
+msgid "Remotes"
+msgstr "මෙම ලුහුබදින්න෠ඉවත් කරන්න."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "මෙම ලුහුබදින්න෠ඉවත් කරන්න."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Remote Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "යතුරු මක෠දමන්න"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "View:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12025,6 +12178,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12868,6 +13022,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "à·à·Šâ€à¶»à·’à¶­:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12880,6 +13067,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12896,6 +13157,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "à·à·Šâ€à¶»à·’à¶­:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12905,6 +13179,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12913,6 +13191,57 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "යතුරු මක෠දමන්න"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "යතුරු පිටපත් කරන්න"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12922,12 +13251,65 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "à·à·Šâ€à¶»à·’à¶­:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13489,7 +13871,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13702,7 +14093,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 09e2d1221d..f7acfad23a 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -366,6 +366,7 @@ msgstr "VytvoriÅ¥ %d NOVÉ track-y a vložiÅ¥ kľúÄe?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -834,6 +835,7 @@ msgstr "Pridať"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -883,8 +885,7 @@ msgstr "Nedá sa pripojiť signál"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1961,7 +1962,6 @@ msgid "New Folder..."
msgstr "Nový PrieÄinok..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Obnoviť"
@@ -2078,7 +2078,8 @@ msgstr "PrieÄinky a Súbory:"
msgid "Preview:"
msgstr "Predzobraziť:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Súbor:"
@@ -2253,7 +2254,7 @@ msgstr "Metóda"
msgid "Signal"
msgstr "Signál"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konštant"
@@ -2284,6 +2285,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3033,8 +3036,9 @@ msgid "Install Android Build Template..."
msgstr "Inštalovať Android Build Template..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Otvoriť Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "OtvoriÅ¥ prieÄinok Editor Data"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3192,10 +3196,6 @@ msgid "Toggle Fullscreen"
msgstr "Prepnúť na Celú Obrazovku"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Prepnúť Systémovú Konzolu"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Otvoriť Editor Data/Settings Folder"
@@ -3429,6 +3429,7 @@ msgid "Load Errors"
msgstr "NaÄítaÅ¥ Chyby"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Zvoliť"
@@ -3509,7 +3510,6 @@ msgid "Author"
msgstr "Autori"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3750,6 +3750,12 @@ msgstr "Cesta Scény:"
msgid "Import From Node:"
msgstr "Importovať Z Node-u:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Chyba!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4658,6 +4664,7 @@ msgid "Subfolder:"
msgstr "Subfolder:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autor:"
@@ -6370,6 +6377,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Pridať %s"
@@ -9860,7 +9868,7 @@ msgid "TileSet"
msgstr "Súbor:"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9868,16 +9876,54 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nieje uvedené žiadne meno."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Komunita"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Zmeniť"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Zmeniť"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komunita"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Naozaj chcete odstrániť všetky pripojenia z tohto signálu?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9889,7 +9935,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Vymazať Bod"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Premenovať"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9899,52 +9975,144 @@ msgstr "Vytvoriť adresár"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
+msgid "Discard all changes"
+msgstr "Parameter sa Zmenil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Ukladanie lokálnych zmien..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Parameter sa Zmenil"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
msgstr "Zmeniť"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Zmeniť"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Komunita"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
+msgid "Branches"
+msgstr "Zhody:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Vytvoriť Nový %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Vymazať Track Animácie"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
msgstr "Všetky vybrané"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Vymazať"
+msgid "Create New Remote"
+msgstr "Vytvoriť Nový %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Zmeniť"
+msgid "Remove Remote"
+msgstr "Vymazať Predmet"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Zmeniť veľkosť výberu"
+msgid "Remote Name"
+msgstr "Diaľkový "
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Remote URL"
+msgstr "Diaľkový "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
+msgid "Renamed"
+msgstr "Všetky vybrané"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Vymazať"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
msgstr "Zmeniť"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "View:"
+msgstr "Zobrazenie"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12534,6 +12702,7 @@ msgid "Export list to a CSV file"
msgstr "Exportovať Profil"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13407,6 +13576,39 @@ msgstr ""
msgid "Edit Member"
msgstr "Súbor:"
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animácie"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13419,6 +13621,84 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Zostávajúce prieÄinky:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Vlastné"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Pridať %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Pridať %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13435,6 +13715,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcie"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Zmeniť veľkosť Array-u"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13444,6 +13738,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13452,6 +13750,64 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Znovu naÄítaÅ¥"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Nastaviť Rukoväť"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konštant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konštant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konštant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konštant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Editovanie Stromu Scén"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Vlastné"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Vložiť"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13461,15 +13817,75 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Volania"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konštanty"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Všetky vybrané"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Vložiť"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Vložiť"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fyzická Snímka %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signál"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signál"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Inštancie"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14065,7 +14481,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14286,7 +14711,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index afb725022c..3c6fc8e571 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -389,6 +389,7 @@ msgstr "Ustvarim %d NOVO sled in vstavim kljuÄe?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -878,6 +879,7 @@ msgstr "Dodaj"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -930,8 +932,7 @@ msgstr "Povezovanje Signala:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2033,7 +2034,6 @@ msgid "New Folder..."
msgstr "Nova Mapa..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Osveži"
@@ -2158,7 +2158,8 @@ msgstr "Mape & Datoteke:"
msgid "Preview:"
msgstr "Predogled:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Datoteka:"
@@ -2350,7 +2351,7 @@ msgstr "Metode"
msgid "Signal"
msgstr "Signali"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstanta"
@@ -2383,6 +2384,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3142,7 +3145,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "Odprem Upravljalnik Projekta?"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3306,11 +3309,6 @@ msgstr "Preklopi na Celozaslonski NaÄin"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Toggle System Console"
-msgstr "Preklopi NaÄin"
-
-#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
msgstr "Nastavitve Urejevalnika"
@@ -3543,6 +3541,7 @@ msgid "Load Errors"
msgstr "Napake pri Nalaganju"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Izberi"
@@ -3624,7 +3623,6 @@ msgid "Author"
msgstr "Avtorji"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3860,6 +3858,12 @@ msgstr "Pot Prizora:"
msgid "Import From Node:"
msgstr "Uvozi iz Gradnika:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Napaka!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4803,6 +4807,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Avtor:"
@@ -6612,6 +6617,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -10147,7 +10153,7 @@ msgid "TileSet"
msgstr "Izvozi PloÅ¡Äno Zbirko"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10155,19 +10161,57 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Ime ni doloÄeno."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Skupnost"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Spremebe v Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Spremebe v Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Skupnost"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Ponastavi PoveÄavo/PomanjÅ¡avo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -10176,7 +10220,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Odstrani toÄko"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Preimenuj"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10186,53 +10260,145 @@ msgstr "Ustvari Nov %s"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Spremeni"
+msgid "Discard all changes"
+msgstr "Spremebe v Shader"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Shranjevanje lokalnih sprememb..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Spremebe v Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Usklajuj Spremembe Skript"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Usklajuj Spremembe Skript"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Skupnost"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Preimenuj"
+msgid "Branches"
+msgstr "Zadetki:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Izbriši"
+msgid "Create New Branch"
+msgstr "Ustvarite Nov Projekt"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Spremeni"
+msgid "Remove Branch"
+msgstr "Odstrani animacijsko sled"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Izbriši Izbrano"
+msgid "Remotes"
+msgstr "Upravljalnik"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Zamenjaj Vse"
+msgid "Create New Remote"
+msgstr "Ustvarite Nov Projekt"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Usklajuj Spremembe Skript"
+msgid "Remove Remote"
+msgstr "Odstrani Predlogo"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Upravljalnik "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Upravljalnik "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+#, fuzzy
+msgid "Renamed"
+msgstr "Preimenuj"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Izbriši"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Spremeni"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "View:"
+msgstr "Pogled"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Uredi krivuljo vozliÅ¡Äa"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12877,6 +13043,7 @@ msgid "Export list to a CSV file"
msgstr "Izvozi Projekt"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13760,6 +13927,40 @@ msgstr "Osveži"
msgid "Edit Member"
msgstr "ÄŒlani"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Trenutna RazliÄica:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animacija"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Vhodni tip ni spremenljiv: "
@@ -13772,6 +13973,84 @@ msgstr "Iterator je bil neveljaven"
msgid "Iterator became invalid: "
msgstr "Iterator je neveljaven: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Preimenovanje mape:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Osnovni Tip:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Samo"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Veljavni znaki:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Neveljaven indeks lastnosti imena."
@@ -13788,6 +14067,20 @@ msgstr "Pot ne vodi do vozliÅ¡Äa!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Neveljaven indeks lastnosti imena '%s' v vozliÅ¡Äu %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcije:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "PoveÄaj Niz"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Neveljaven argument od tipa: "
@@ -13797,6 +14090,10 @@ msgid ": Invalid arguments: "
msgstr ": Neveljavni argumenti: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet ni najden v skripti: "
@@ -13805,6 +14102,65 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet ni najden v skripti: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Dodaj prednaloženo vozliÅ¡Äe"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "NaÄin PloÅ¡Äe"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "NaÄin PloÅ¡Äe"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Gradnik ÄŒasovniIskalnik"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Shrani Prizor"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Samo"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Gradnik Prehod"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "VozliÅ¡Äe po meri nima metode _step(); grafa ni mogoÄe obdelati."
@@ -13816,15 +14172,77 @@ msgstr ""
"Neveljavna vrnitev vrednosti od _step(), mora biti število (seq out), ali "
"string (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Klici"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstante"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Lokalno prostorski naÄin (%s)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Lokalno prostorski naÄin (%s)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Premakni Dejanje"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Odstrani Gradnik VizualnaSkripta"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "NaÄin Premika"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fizikalni Okvir %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signali"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signali"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Primer"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14426,7 +14844,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14646,7 +15073,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 6669292e99..6e4a0c84fe 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -362,6 +362,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -819,6 +820,7 @@ msgstr "Shto"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -871,8 +873,7 @@ msgstr "Lidh Sinjalin: "
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1981,7 +1982,6 @@ msgid "New Folder..."
msgstr "Folder i Ri..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Rifresko"
@@ -2102,7 +2102,8 @@ msgstr "Direktorit & Skedarët:"
msgid "Preview:"
msgstr "Shikim paraprak:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Skedar:"
@@ -2283,7 +2284,7 @@ msgstr "Metodat"
msgid "Signal"
msgstr "Sinjalet"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2316,6 +2317,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3080,8 +3083,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Hap Folderin e të Dhënave të Projektit"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Hap Folderin e të Dhënave të Editorit"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3243,11 +3247,6 @@ msgid "Toggle Fullscreen"
msgstr "Ndrysho Ekranin e Plotë"
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Ndrysho metodën e ndarjes"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Hap Folderin e Editorit për të Dhënat/Opsionet"
@@ -3476,6 +3475,7 @@ msgid "Load Errors"
msgstr "Ngarko Gabimet"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Zgjidh"
@@ -3556,7 +3556,6 @@ msgid "Author"
msgstr "Autorët"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3797,6 +3796,12 @@ msgstr "Rruga Skenës:"
msgid "Import From Node:"
msgstr "Importo nga Nyja:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Pasqyrë"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4727,6 +4732,7 @@ msgid "Subfolder:"
msgstr "Subfolderi:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Autori:"
@@ -6406,6 +6412,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9808,7 +9815,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9816,16 +9823,54 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Nuk u dha një emër."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Komuniteti"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Ndrysho"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Ndrysho"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Komuniteti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "A jeni i sigurt që doni të hiqni të gjitha lidhjet nga ky sinjal?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9837,7 +9882,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Hiq Artikullin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Riemërto"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9846,9 +9921,109 @@ msgid "Detect new changes"
msgstr "Sinkronizo Nryshimet e Skenës"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Ndrysho"
+msgid "Stage all changes"
+msgstr "Duke ruajtur ndryshimet lokale..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Duke ruajtur ndryshimet lokale..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Sinkronizo Ndryshimet e Shkrimit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Sinkronizo Ndryshimet e Shkrimit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Komuniteti"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Përputhjet:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Krijo %s të ri"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Hiq Artikullin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Hiq"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Krijo %s të ri"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Hiq Artikullin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Emri i Nyjes:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Hiq"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9870,29 +10045,20 @@ msgid "Typechange"
msgstr "Ndrysho"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "Stage Selected"
-msgstr "Zgjidh"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Sinkronizo Ndryshimet e Shkrimit"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
+msgid "View:"
+msgstr "Shikim paraprak:"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12478,6 +12644,7 @@ msgid "Export list to a CSV file"
msgstr "Eksporto Projektin"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13334,6 +13501,40 @@ msgstr "Rifresko"
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Versioni Aktual:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Animacionet:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13346,6 +13547,83 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Duke riemërtuar folderin:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Vetja"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Karakteret e lejuar:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13362,6 +13640,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funksionet:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13371,6 +13662,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13379,6 +13674,62 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstantet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstantet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstantet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstantet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Fshi Nyjen"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Ruaj Skenën"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Vetja"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Dyfisho Nyjet"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13388,14 +13739,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Thërritjet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Konstantet"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Funksionet:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Lëviz të Preferuarën Lartë"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Hapi i Fizikës %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinjalet"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinjalet"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instanco"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -13975,7 +14386,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14190,7 +14610,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index fb013c20a9..95723f17e4 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -401,6 +401,7 @@ msgstr "Ðаправите %d нових трака и убаците кључе
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -921,6 +922,7 @@ msgstr "Додај"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -975,8 +977,7 @@ msgstr "Везујући Ñигнал:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2123,7 +2124,6 @@ msgid "New Folder..."
msgstr "Ðови директоријум..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "ОÑвежи"
@@ -2248,7 +2248,8 @@ msgstr "Директоријуми и датотеке:"
msgid "Preview:"
msgstr "Преглед:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Датотека:"
@@ -2447,7 +2448,7 @@ msgstr "Методе"
msgid "Signal"
msgstr "Сигнали"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "КонÑтантан"
@@ -2481,6 +2482,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Set %s"
@@ -3266,8 +3269,8 @@ msgstr "ИнÑталирај Android образце градње"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
-msgstr "Отвори менаџер пројекта?"
+msgid "Open User Data Folder"
+msgstr "Отвори Фолдер Уређивача Података"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3432,11 +3435,6 @@ msgstr "Укљ./ИÑкљ. режим целог екрана"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Toggle System Console"
-msgstr "Промени режим"
-
-#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
msgstr "ПоÑтавке уредника"
@@ -3690,6 +3688,7 @@ msgid "Load Errors"
msgstr "Учитај грешке"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Одабери"
@@ -3774,7 +3773,6 @@ msgid "Author"
msgstr "Ðутори"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
#, fuzzy
msgid "Status"
@@ -4038,6 +4036,12 @@ msgstr "Пут Ñцене:"
msgid "Import From Node:"
msgstr "Увоз преко чвора:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Грешка"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -5019,6 +5023,7 @@ msgid "Subfolder:"
msgstr "ПодФолдер:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Ðутор:"
@@ -6912,6 +6917,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Додај %s"
@@ -10685,7 +10691,7 @@ msgstr "TileSet..."
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr " VCS додатци ниÑу доÑтупни."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10693,9 +10699,14 @@ msgid "Error"
msgstr "Грешка"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "No files added to stage"
-msgstr "Ðи један фајл није додат на позорницу"
+msgid "No commit message was provided."
+msgstr "Име није дато."
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -10704,8 +10715,41 @@ msgstr "Заједница"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "VCS Addon is not initialized"
-msgstr "VCS додатак није иницијализован"
+msgid "Staged Changes"
+msgstr "Промене шејдера"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Промене шејдера"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Заједница"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Под-Ñтабло"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Да ли Ñигурно желиш да отвориш више одједног пројекта?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "РеÑетуј увеличање"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -10719,8 +10763,37 @@ msgstr "Велика Ñлова"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Staging area"
-msgstr "СценÑки проÑтор"
+msgid "Remote Login"
+msgstr "Обриши тачку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Преименуј"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -10729,8 +10802,112 @@ msgstr "Ðаправи нов"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr "Промене шејдера"
+msgid "Discard all changes"
+msgstr ""
+"Затвори и Ñачувај измене?\n"
+"\""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Чувам локалне промене..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Промене материјала"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Синхронизуј промене Ñкриптица"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Синхронизуј промене Ñкриптица"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Заједница"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Подударање:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Креирај Ðов Пројекат"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Обриши траку анимације"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Удаљени уређај"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Креирај Ðов Пројекат"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Обриши Ñтавку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Удаљени уређај "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Удаљени уређај "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Изворна мрежа:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -10753,34 +10930,23 @@ msgid "Typechange"
msgstr "Промена типа"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "Stage Selected"
-msgstr "Увећај одабрано"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "Stage All"
-msgstr "Сачувај Ñве"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
-msgid "Commit Changes"
-msgstr "Синхронизуј промене Ñкриптица"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "View file diffs before committing them to the latest version"
-msgstr "Погледај фајл разлике пре него га предаш задњој верзији."
+msgid "View:"
+msgstr "Поглед"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "No file diff is active"
-msgstr "Ðи једна фајл разлика није активна"
+msgid "Split"
+msgstr "Раздели пут"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Detect changes in file diff"
-msgstr "Пронађене промене у фајл разликама"
+msgid "Unified"
+msgstr "Измењено"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -13971,6 +14137,7 @@ msgid "Export list to a CSV file"
msgstr "Извези лиÑту у CSV фајл"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#, fuzzy
msgid "Resource Path"
msgstr "Путања РеÑурÑа"
@@ -14959,6 +15126,40 @@ msgstr "ОÑвежи"
msgid "Edit Member"
msgstr "Чланови"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "ПоÑтави правоугаони регион"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Ðнимација"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -14971,6 +15172,89 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Преименовање директоријума:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Лево-ДеÑно"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Тип:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Сам"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Код карактера %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Додај %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "ПоÑтави %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Додај %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+#, fuzzy
+msgid "Get %s"
+msgstr "Повуци %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -14987,6 +15271,21 @@ msgstr "Путања не води ка чвору!"
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "ПоÑтави %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Промени векторÑку функцију"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Промени величину низа"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -14996,6 +15295,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -15006,6 +15309,66 @@ msgstr "СкупПроменљивих није нађен у Ñкрипти:"
#: modules/visual_script/visual_script_nodes.cpp
#, fuzzy
+msgid "Preload"
+msgstr "ОÑвежи"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Режим инÑпекције"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Режим инÑпекције"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "КонÑтантан"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "КонÑтантан"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "КонÑтантан"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "КонÑтантан"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Омогућен GDNative Singleton"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek чвор"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Едитовање Стабла Сцене"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Сам"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Ðаправи чвор"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
msgid "Custom node has no _step() method, can't process graph."
msgstr "Произвољни чвор нема _step() методу, граф не моће бити обрађен."
@@ -15018,15 +15381,76 @@ msgstr ""
"Ðеважећа повратна вредноÑÑ‚ од _step(), мора бити интиџер (seq out), или "
"Ñтринг (грешка)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Позиви цртања"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Ðепроменљиве"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Режим Ñкалирања (R)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Режим Ñкалирања (R)"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Радња"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Потражи VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
#, fuzzy
-msgid "Get %s"
-msgstr "Повуци %s"
+msgid "Next Frame"
+msgstr "Ðалепи оквир"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Слика физике %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Сигнали"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Сигнали"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Додај инÑтанцу"
#: platform/android/export/export_plugin.cpp
#, fuzzy
@@ -15711,12 +16135,21 @@ msgstr "ПаралакÑСлој чвор Ñамо ради кад је дете
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"ЧеÑтице базиране на графичкој ниÑу подржане од Ñтране GLES2 видео "
"управљача.\n"
"УмеÑто тога кориÑти ПроцеÑорЧеÑтице2Д чвор."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
#, fuzzy
msgid ""
@@ -16003,10 +16436,18 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr "GPU-базиране чеÑтице ниÑу подржане од Ñтране GLES2 видео управљача."
#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
#, fuzzy
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 9a5bbeb2ec..a3db7ebbae 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -376,6 +376,7 @@ msgstr "Napravi %d novih kanala i dodaj kljuÄeve?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -837,6 +838,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -886,8 +888,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1916,7 +1917,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2035,7 +2035,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2205,7 +2206,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Kontanta"
@@ -2236,6 +2237,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2934,7 +2937,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3070,10 +3073,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3293,6 +3292,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3370,7 +3370,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3598,6 +3597,12 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Ogledalo"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4457,6 +4462,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6141,6 +6147,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9515,7 +9522,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9523,7 +9530,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9532,7 +9544,36 @@ msgid "Commit"
msgstr "Zajednica"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Zajednica"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9544,7 +9585,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Obriši Selekciju"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Animacija Preimenuj Kanal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9553,50 +9624,139 @@ msgid "Detect new changes"
msgstr "Napravi"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Napravi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Animacija Preimenuj Kanal"
+msgid "Commit Message"
+msgstr "Zajednica"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "Animacija ObriÅ¡i KljuÄeve"
+msgid "Commit List"
+msgstr "Zajednica"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Skaliraj Selekciju"
+msgid "Create New Branch"
+msgstr "Napravi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Odstrani Kanal Animacije"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Branch Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+#, fuzzy
+msgid "Remotes"
+msgstr "Obriši Selekciju"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Napravi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Obriši Selekciju"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Obriši Selekciju"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Animacija Preimenuj Kanal"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Animacija ObriÅ¡i KljuÄeve"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Izmjeni Krivulju ÄŒvora"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12135,6 +12295,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12985,6 +13146,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Optimizuj Animaciju"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12997,6 +13191,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13013,6 +13281,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funkcije:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13022,6 +13303,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13030,6 +13315,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Kontanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Kontanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Kontanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Kontanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Animacija ObriÅ¡i KljuÄeve"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Napravi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Animacija Uduplaj KljuÄeve"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13039,12 +13379,66 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Kontanta"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Sve sekcije"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13606,7 +14000,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13819,7 +14222,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index b8c190d92a..87d39fb5ee 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -379,6 +379,7 @@ msgstr "Skapa %d NYA spår och infoga nycklar?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -849,6 +850,7 @@ msgstr "Lägg till"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -900,8 +902,7 @@ msgstr "Kan ej ansluta signal"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1978,7 +1979,6 @@ msgid "New Folder..."
msgstr "Ny Mapp..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Uppdatera"
@@ -2095,7 +2095,8 @@ msgstr "Kataloger & Filer:"
msgid "Preview:"
msgstr "Förhandsvisning:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Fil:"
@@ -2288,7 +2289,7 @@ msgstr "Metoder"
msgid "Signal"
msgstr "Signaler"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Konstant"
@@ -2321,6 +2322,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3092,7 +3095,8 @@ msgid "Install Android Build Template..."
msgstr "Installera Android Build Template..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
msgstr "Öppna Projekthanteraren"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3230,11 +3234,6 @@ msgid "Toggle Fullscreen"
msgstr "Växla Fullskärm"
#: editor/editor_node.cpp
-#, fuzzy
-msgid "Toggle System Console"
-msgstr "Växla Läge"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3463,6 +3462,7 @@ msgid "Load Errors"
msgstr "Ladda Felmeddelanden"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Välj"
@@ -3544,7 +3544,6 @@ msgid "Author"
msgstr "Författare"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Status"
@@ -3776,6 +3775,12 @@ msgstr "Scen Filsökväg:"
msgid "Import From Node:"
msgstr "Importera Från Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Fel"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4713,6 +4718,7 @@ msgid "Subfolder:"
msgstr "Undermapp:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Författare:"
@@ -6439,6 +6445,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Lägg till %s"
@@ -9951,7 +9958,7 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9959,19 +9966,58 @@ msgid "Error"
msgstr "Fel"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "Inget namn har angetts."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "Community"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Shader Ändringar:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Shader Ändringar:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Community"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Är du säker att du vill ta bort alla kopplingar från denna signal?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Återställ Zoom"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -9980,7 +10026,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Flytta Ner"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Byt namn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9989,53 +10065,146 @@ msgid "Detect new changes"
msgstr "Skapa Ny"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Ändringar"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Stäng och spara ändringar?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Lagrar lokala ändringar..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materialförändringar:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Synkronisera Skript-ändringar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "Synkronisera Skript-ändringar"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Community"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "Byt namn"
+msgid "Branches"
+msgstr "Matchar:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
+msgid "Create New Branch"
+msgstr "Skapa Nytt Projekt"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Ta bort Anim spår"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
msgstr "Ta bort"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "Ändra"
+msgid "Create New Remote"
+msgstr "Skapa Nytt Projekt"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Skala urval"
+msgid "Remove Remote"
+msgstr "Ta Bort Mall"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Spara Alla"
+msgid "Remote Name"
+msgstr "Node Namn:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Synkronisera Skript-ändringar"
+msgid "Remote URL"
+msgstr "Ta bort"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "Byt namn"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "Ta bort"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Ändra"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Visa"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Redigera Nodkurva"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12636,6 +12805,7 @@ msgid "Export list to a CSV file"
msgstr "Exportera Projekt"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13496,6 +13666,40 @@ msgstr "Uppdatera"
msgid "Edit Member"
msgstr "Medlemmar"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Ställ in uttryck"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animering"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13508,6 +13712,87 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Byter namn på mappen:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Växla"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Typ:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Själv"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Vid tecken %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Lägg till %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Lägg till %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13524,6 +13809,20 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Funktioner"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ändra storlek på Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13533,6 +13832,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet hittades inte i Skript: "
@@ -13541,6 +13844,65 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet hittades inte i Skript: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Ladda om"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Automatisk Indentering"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Automatisk Indentering"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Ny Scenrot"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Scenträd Redigering"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Själv"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Klipp ut Noder"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13550,15 +13912,76 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Begränsningar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Gör Patch"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Gör Patch"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Åtgärd"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "Fäst Skript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Flytta Nod(er)"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fysik Bildruta %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Signaler"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Signaler"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instans"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14150,7 +14573,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14377,7 +14809,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index b7c8cf73e3..4de4a497eb 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -375,6 +375,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -832,6 +833,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -881,8 +883,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1910,7 +1911,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2027,7 +2027,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2195,7 +2196,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2225,6 +2226,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2922,7 +2925,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3058,10 +3061,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3279,6 +3278,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3356,7 +3356,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3583,6 +3582,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4442,6 +4446,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6109,6 +6114,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9425,7 +9431,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9433,7 +9439,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9441,7 +9452,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9453,7 +9492,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9461,50 +9530,133 @@ msgid "Detect new changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Stage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯"
+msgid "Remove Branch"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+msgid "Remotes"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Create New Remote"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+msgid "Remove Remote"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதையை நீகà¯à®•à¯"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Remote Name"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Remote URL"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Fetch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "அசைவூடà¯à®Ÿà¯ பாதைகà¯à®•௠மறà¯à®ªà¯†à®¯à®°à¯ இடà¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "கண௠வளைவை[Node Curve] திரà¯à®¤à¯à®¤à¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12030,6 +12182,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12873,6 +13026,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "மாறà¯à®±à®™à¯à®•ளை இதறà¯à®•௠அமை:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12885,6 +13071,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12901,6 +13161,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12910,6 +13183,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12918,6 +13195,56 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "அசைவூடà¯à®Ÿà¯ போலிபசà¯à®šà®¾à®µà®¿à®•ளà¯"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12927,12 +13254,66 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "சேர௠மà¯à®•à¯à®•ியபà¯à®ªà¯à®³à¯à®³à®¿à®¯à¯ˆ நகரà¯à®¤à¯à®¤à¯"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13494,7 +13875,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13707,7 +14097,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 448aa534eb..8c86f7f276 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -358,6 +358,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -807,6 +808,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -856,8 +858,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1880,7 +1881,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1997,7 +1997,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2165,7 +2166,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3244,6 +3243,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3320,7 +3320,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3545,6 +3544,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4400,6 +4404,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6043,6 +6048,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9325,7 +9331,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9333,7 +9339,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9342,7 +9353,36 @@ msgid "Commit"
msgstr "సంఘం"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "సంఘం"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9354,55 +9394,165 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "సంఘం"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Commit List"
+msgstr "సంఘం"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11911,6 +12061,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12739,6 +12890,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12751,6 +12934,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12767,6 +13024,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12776,6 +13045,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12784,6 +13057,58 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12793,12 +13118,66 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "à°¸à±à°¥à°¿à°°à°¾à°‚కాలà±"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "సంకేతాలà±"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13360,7 +13739,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13573,7 +13961,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/th.po b/editor/translations/th.po
index acb8f8cbf3..4f1443f031 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -374,6 +374,7 @@ msgstr "เพิ่มà¹à¸—ร็à¸à¹ƒà¸«à¸¡à¹ˆ %d à¹à¸—ร็à¸à¹à¸¥à¸°à¹
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -838,6 +839,7 @@ msgstr "เพิ่ม"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -887,8 +889,7 @@ msgstr "ไม่สามารถเชื่อมต่อสัà¸à¸à¸²à¸“
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1959,7 +1960,6 @@ msgid "New Folder..."
msgstr "สร้างโฟลเดอร์..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "รีเฟรช"
@@ -2076,7 +2076,8 @@ msgstr "ไฟล์à¹à¸¥à¸°à¹‚ฟลเดอร์:"
msgid "Preview:"
msgstr "ตัวอย่าง:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "ไฟล์:"
@@ -2249,7 +2250,7 @@ msgstr "เมธอด"
msgid "Signal"
msgstr "สัà¸à¸à¸²à¸“"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "คงที่"
@@ -2280,6 +2281,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "ตั้ง %s"
@@ -3012,8 +3015,9 @@ msgid "Install Android Build Template..."
msgstr "ติดตั้งเทมเพลตà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¸‚องà¹à¸­à¸™à¸”รอยด์"
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "เปิดโฟลเดอร์ข้อมูลโปรเจà¸à¸•์"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "เปิดโฟลเดอร์ของตัวà¹à¸à¹‰à¹„ข"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3164,10 +3168,6 @@ msgid "Toggle Fullscreen"
msgstr "เปิด/ปิด โหมดเต็มหน้าจอ"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "เปิด/ปิด คอนโซลระบบ"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "เปิดโฟลเดอร์ข้อมูล/ตั้งค่าของตัวà¹à¸à¹‰à¹„ข"
@@ -3400,6 +3400,7 @@ msgid "Load Errors"
msgstr "โหลดผิดพลาด"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "เลือà¸"
@@ -3480,7 +3481,6 @@ msgid "Author"
msgstr "ทีมงาน"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "สถานะ"
@@ -3716,6 +3716,12 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่อยู่ฉาà¸:"
msgid "Import From Node:"
msgstr "นำเข้าจาà¸à¹‚หนด:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "ผิดพลาด"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4617,6 +4623,7 @@ msgid "Subfolder:"
msgstr "โฟลเดอร์ย่อย:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "ผู้สร้าง:"
@@ -6301,6 +6308,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "เพิ่ม %s"
@@ -9752,7 +9760,8 @@ msgid "TileSet"
msgstr "ไทล์เซต"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "ไม่พบส่วนเสริม VCS"
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9760,16 +9769,56 @@ msgid "Error"
msgstr "ผิดพลาด"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "ไม่มีไฟล์เพิ่มไฟยัง stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "ไม่ได้ระบุชื่อ"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Commit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "ส่วนเสริม VCS ยังไม่ได้ใช้งาน"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "จำนวนครั้งที่เปลี่ยน Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "จำนวนครั้งที่เปลี่ยน Shader"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "ผังย่อย"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "ยืนยันà¸à¸²à¸£à¹€à¸›à¸´à¸”โปรเจà¸à¸•์มาà¸à¸à¸§à¹ˆà¸² 1 โปรเจà¸à¸•์?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "นำà¸à¸²à¸£à¸£à¸µà¹€à¸‹à¹‡à¸•ไปใช้"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9780,16 +9829,148 @@ msgid "Initialize"
msgstr "เริ่มต้น"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Stage พื้นที่"
+#, fuzzy
+msgid "Remote Login"
+msgstr "ลบจุด"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "เปลี่ยนชื่อ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "พบà¸à¸²à¸£à¹à¸à¹‰à¹„ขใหม่"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "เปลี่ยน"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "ปิดà¹à¸¥à¸°à¸šà¸±à¸™à¸—ึà¸?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "เà¸à¹‡à¸šà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¸ à¸²à¸¢à¹ƒà¸™..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "จำนวนครั้งที่เปลี่ยนวัสดุ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Commit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "พบ:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "สร้างโปรเจà¸à¸•์ใหม่"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "ลบà¹à¸—ร็à¸à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "ระยะไà¸à¸¥"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "สร้างโปรเจà¸à¸•์ใหม่"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "ลบไอเทม"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "ควบคุม "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "ควบคุม "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Mesh ต้นฉบับ:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9808,28 +9989,23 @@ msgid "Typechange"
msgstr "เปลี่ยนชนิด"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "เลือภstage"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Stage ทั้งหมด"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "à¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡ commit"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "ดู diffs ของไฟล์à¸à¹ˆà¸­à¸™à¸—ี่จะ commit ไปยังเวอร์ชันล่าสุด"
+#, fuzzy
+msgid "View:"
+msgstr "มุมมอง"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "ไม่มีà¸à¸²à¸£à¹ƒà¸Šà¹‰à¸‡à¸²à¸™à¹„ฟล์ diff"
+#, fuzzy
+msgid "Split"
+msgstr "ตัดเส้น"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "ตรวจสอบà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡à¹ƒà¸™ file diff"
+#, fuzzy
+msgid "Unified"
+msgstr "à¹à¸à¹‰à¹„ขà¹à¸¥à¹‰à¸§"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12466,6 +12642,7 @@ msgid "Export list to a CSV file"
msgstr "ส่งออà¸à¸£à¸²à¸¢à¸à¸²à¸£à¹€à¸›à¹‡à¸™à¹„ฟล์ CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ª"
@@ -13308,6 +13485,40 @@ msgstr "รีเฟรชà¸à¸£à¸²à¸Ÿ"
msgid "Edit Member"
msgstr "à¹à¸à¹‰à¹„ขสมาชิà¸"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "ตั้งค่านิพจน์"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "à¹à¸­à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "ตัวà¹à¸›à¸£à¸›à¸£à¸°à¹€à¸ à¸—นี้ใช้วนซ้ำไม่ได้: "
@@ -13320,6 +13531,88 @@ msgstr "ตัววนซ้ำใช้ไม่ได้อีà¸à¸•่อไ
msgid "Iterator became invalid: "
msgstr "ตัววนซ้ำใช้ไม่ได้: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "เปลี่ยนชื่อโฟลเดอร์:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Pitch"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "ประเภท:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "ตัวเอง"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "ตัวอัà¸à¸©à¸£à¸—ี่ใช้ได้ %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "เพิ่ม %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "ตั้ง %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "เพิ่ม %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "รับ %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "ไม่พบคุณสมบัติ"
@@ -13336,6 +13629,21 @@ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่ระบุไม่ได้นำไป
msgid "Invalid index property name '%s' in node %s."
msgstr "ไม่พบคุณสมบัติ '%s' ในโหนด %s"
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "ตั้ง %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "ฟังà¸à¹Œà¸Šà¸±à¸™"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "ปรับขนาดอาร์เรย์"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": ประเภทตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้อง: "
@@ -13345,6 +13653,10 @@ msgid ": Invalid arguments: "
msgstr ": ตัวà¹à¸›à¸£à¹„ม่ถูà¸à¸•้อง: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "ไม่พบ VariableGet ในสคริปต์: "
@@ -13353,6 +13665,66 @@ msgid "VariableSet not found in script: "
msgstr "ไม่พบ VariableSet ในสคริปต์: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "โหลดใหม่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z Index"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "คงที่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "คงที่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "คงที่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "คงที่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "เปิดà¸à¸²à¸£à¸—ำงานซิงเà¸à¸´à¸¥à¸•ัน GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "โหนด TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "à¹à¸à¹‰à¹„ขผังฉาà¸"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "ตัวเอง"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "ตัดโหนด"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "โหนดà¸à¸³à¸«à¸™à¸”เองไม่มีเมท็อด _step() ไม่สามารถประมวลผลà¸à¸£à¸²à¸Ÿà¹„ด้"
@@ -13362,13 +13734,75 @@ msgid ""
"(error)."
msgstr "ค่าคืนจาภ_step() ผิดพลาด ต้องเป็นจำนวนเต็ม (ลำดับ) หรือสตริง (ข้อผิดพลาด)"
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "จำนวนครั้ง"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "ค่าคงที่"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "ใช้พื้นที่ภายใน"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "ใช้พื้นที่ภายใน"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "à¸à¸²à¸£à¸à¸£à¸°à¸—ำ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "ค้นหาโหนด VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "รับ %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "เลื่อนเฟรม"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "% ของเฟรมฟิสิà¸à¸ªà¹Œ"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "สัà¸à¸à¸²à¸“"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "สัà¸à¸à¸²à¸“"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "อินสà¹à¸•นซ์"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13982,14 +14416,24 @@ msgid ""
msgstr "ParallaxLayer จะทำงานได้ต้องเป็นโหนดลูà¸à¸‚องโหนด ParallaxBackground"
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"ไดรเวอร์ GLES2 ไม่สนับสนุนระบบพาร์ติเคิลโดยใช้à¸à¸²à¸£à¹Œà¸”จอ\n"
"ใช้โหนด CPUParticles2D à¹à¸—น คุณสามารถใช้ตัวเลือภ\"à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles\" ได้"
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14217,16 +14661,25 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"ไดรเวอร์ GLES2 ไม่สนับสนุนระบบพาร์ติเคิลโดยใช้à¸à¸²à¸£à¹Œà¸”จอ\n"
"ใช้โหนด CPUParticles à¹à¸—น คุณสามารถใช้ตัวเลือภ\"à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles\" ได้"
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "ไม่มีà¸à¸²à¸£à¹à¸ªà¸”งผลเนื่องจาà¸à¹„ม่ได้à¸à¸³à¸«à¸™à¸” mesh ใน draw pass"
diff --git a/editor/translations/tl.po b/editor/translations/tl.po
index 3e48f9d911..ecf0928c49 100644
--- a/editor/translations/tl.po
+++ b/editor/translations/tl.po
@@ -362,6 +362,7 @@ msgstr "Gumawa ng %d BAGONG mga track at maglagay ng mga key?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -830,6 +831,7 @@ msgstr "Maglagay"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -881,8 +883,7 @@ msgstr "Hindi maikabit ang hudyat"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1920,7 +1921,6 @@ msgid "New Folder..."
msgstr "Bagong Folder..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "I-refresh"
@@ -2037,7 +2037,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "File:"
@@ -2210,7 +2211,7 @@ msgstr "Method"
msgid "Signal"
msgstr "Hudyat"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Constant"
@@ -2241,6 +2242,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Itakda ang %s"
@@ -2944,7 +2947,8 @@ msgid "Install Android Build Template..."
msgstr "Ikabit ang Android Build Template..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+#, fuzzy
+msgid "Open User Data Folder"
msgstr "Buksan ang Folder ng Datos ng Proyekto"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3080,10 +3084,6 @@ msgid "Toggle Fullscreen"
msgstr "Pumalit sa Buong Tabing"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3300,6 +3300,7 @@ msgid "Load Errors"
msgstr "Mga Kabugian Sa Pagloload"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Magpili"
@@ -3376,7 +3377,6 @@ msgid "Author"
msgstr "May-akda"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Kalagayan"
@@ -3601,6 +3601,12 @@ msgstr "Kinalalagyan ng Eksena:"
msgid "Import From Node:"
msgstr "Magangkat mula sa Node:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Nabigo"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4458,6 +4464,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6113,6 +6120,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9402,7 +9410,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9410,15 +9418,53 @@ msgid "Error"
msgstr "Nabigo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Walang pangalang binagay."
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "Magcommit"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Mga Pagbabago"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Mga Pagbabago"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Magcommit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Gusto mo bang alisin lahat ng pagkakabit sa hudyat na ito?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9430,7 +9476,37 @@ msgid "Initialize"
msgstr "Simulan"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Alisin ang Hudyat"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Inibang Pangalan"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9438,8 +9514,107 @@ msgid "Detect new changes"
msgstr "Pansinin ang anumang pagbabago"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Mga Pagbabago"
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Pansinin ang anumang pagbabago"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "I-commit Lahat ng Pagbabago"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "I-commit Lahat ng Pagbabago"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "Magcommit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Mga Tugma:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Gumawa ng Bagong %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Alisin ang Anim Track"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Alisin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Gumawa ng Bagong %s"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Alisin ang Gamit"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Pangalan ng Node:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Alisin"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9458,28 +9633,22 @@ msgid "Typechange"
msgstr "Pagbabago ng uri"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr ""
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "I-commit Lahat ng Pagbabago"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
+#, fuzzy
+msgid "View:"
+msgstr "Tingnan"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr ""
+#, fuzzy
+msgid "Unified"
+msgstr "Binago"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -11989,6 +12158,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12817,6 +12987,40 @@ msgstr ""
msgid "Edit Member"
msgstr "Ayusin ang Kasapi"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Ibahin ang Ekspresyon"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animation"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12829,6 +13033,83 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Mga Uri:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Sarili"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Itakda ang %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12845,6 +13126,21 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr "Di-wastong index ng pangalan ng katangian na '%s' sa node %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Itakda ang %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Mga Punsyon:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Ibahin Ang Sukat ng Array"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12854,6 +13150,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12862,6 +13162,64 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Index ng Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Index ng Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Constant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Panibagong Eksena"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Panibagong Eksena"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Sarili"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Kopyahin ang mga Node"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12871,12 +13229,70 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Mga Tawag"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Mga Konstant"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Mga Punsyon:"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Maghanap ng VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Susunod na tab"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Hudyat"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Hudyat"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13440,7 +13856,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13653,7 +14078,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 221e209621..f318616c3e 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -421,6 +421,7 @@ msgstr "%d YENİ izler oluştur ve anahtarlar gir?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -889,6 +890,7 @@ msgstr "Ekle"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -938,8 +940,7 @@ msgstr "Sinyale bağlanamıyor"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2005,7 +2006,6 @@ msgid "New Folder..."
msgstr "Yeni Klasör..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Yenile"
@@ -2122,7 +2122,8 @@ msgstr "Dizinler & Dosyalar:"
msgid "Preview:"
msgstr "Önizleme:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Dosya:"
@@ -2298,7 +2299,7 @@ msgstr "Metot"
msgid "Signal"
msgstr "Sinyal"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Sabit"
@@ -2329,6 +2330,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Ayarla %s"
@@ -3084,8 +3087,9 @@ msgid "Install Android Build Template..."
msgstr "Android İnşa Şablonunu Yükle ..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Proje Verileri Klasörünü Aç"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Düzenleyici Verileri Klasörünü Aç"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3244,10 +3248,6 @@ msgid "Toggle Fullscreen"
msgstr "Tam Ekranı Aç/Kapat"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Sistem Terminalini Aç / Kapat"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Düzenleyici Verileri/Ayarları Klasörünü Aç"
@@ -3478,6 +3478,7 @@ msgid "Load Errors"
msgstr "Hataları Yükle"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Seç"
@@ -3554,7 +3555,6 @@ msgid "Author"
msgstr "Yaratıcı"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Durum"
@@ -3799,6 +3799,12 @@ msgstr "Sahne Yolu:"
msgid "Import From Node:"
msgstr "Düğümden İçe Aktar:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Hata"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Bu şablonları içeren klasörü açın."
@@ -4692,6 +4698,7 @@ msgid "Subfolder:"
msgstr "Alt Klasör:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Yazar:"
@@ -6386,6 +6393,7 @@ msgid "Zoom to 1600%"
msgstr "%1600'e yakınlaştır"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Ekle %s"
@@ -9759,7 +9767,8 @@ msgid "TileSet"
msgstr "DöşemeTakımı"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Hiçbir VCS eklentisi mevcut değil."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9767,16 +9776,56 @@ msgid "Error"
msgstr "Hata"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Sahneye hiç dosya eklenmedi"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "SaÄŸlanan isim yok."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "İşle"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS eklentileri etkinleÅŸtirilmedi"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Gölgelendirici Değişiklikleri:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Gölgelendirici Değişiklikleri:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "İşle"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Altağaç"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Birden fazla proje açmakta kararlı mısınız?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Sıfırla"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9787,16 +9836,148 @@ msgid "Initialize"
msgstr "EtkinleÅŸtir"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Sahne Öncesi"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Noktayı kaldır"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Yeniden Adlandır"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Yeni deÄŸiÅŸiklikleri tespit et"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "DeÄŸiÅŸiklikler"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Kapa ve deÄŸiÅŸiklikleri kaydet?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Yerel değişiklikler kayıt ediliyor..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Materyal DeÄŸiÅŸiklikleri:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "Değişiklikleri İşle"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "Değişiklikleri İşle"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "İşle"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "EÅŸleÅŸmeler:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Yeni Proje OluÅŸtur"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Animasyon İzini Kaldır"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Uzak"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Yeni Proje OluÅŸtur"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Öğeyi Kaldır"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Uzak "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Uzak "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Kaynak Örüntü:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9815,28 +9996,23 @@ msgid "Typechange"
msgstr "Türdeğiştir"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Sahne Seçildi"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "Tümünü Sahneye Al"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "Değişiklikleri İşle"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Son versiyona işlemeden önce dosya diff 'lerini incele"
+#, fuzzy
+msgid "View:"
+msgstr "Görüş"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Dosya diff etkin deÄŸil"
+#, fuzzy
+msgid "Split"
+msgstr "Yolu Ayır"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "Diff dosyasındaki değişiklikleri tespit et"
+#, fuzzy
+msgid "Unified"
+msgstr "DeÄŸiÅŸti"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12522,6 +12698,7 @@ msgid "Export list to a CSV file"
msgstr "Listeyi CSV dosyasına aktar"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "Kaynak Yolu"
@@ -13365,6 +13542,40 @@ msgstr "GrafiÄŸi Yenile"
msgid "Edit Member"
msgstr "Üye Düzenle"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "İfadeyi ayarla"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "animasyon"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Girdi türü yinelenebilir değil: "
@@ -13377,6 +13588,88 @@ msgstr "Yineleyici geçersiz durumda"
msgid "Iterator became invalid: "
msgstr "Yineleyici geçersiz durumda: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Klasör yeniden adlandırma:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Perde:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Türler:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Kendi"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "%s karakterinde"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Ekle %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Ayarla %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Ekle %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Getir %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Geçersiz indeks özelliği ismi."
@@ -13393,6 +13686,21 @@ msgstr "Yol bir düğüme çıkmıyor!"
msgid "Invalid index property name '%s' in node %s."
msgstr "%s düğümünde geçersiz indeks özelliği ismi '%s'."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Ayarla %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "İşlevler"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Diziyi Yeniden Boyutlandır"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Şu tür için geçersiz değiştirgen: "
@@ -13402,6 +13710,10 @@ msgid ": Invalid arguments: "
msgstr ": Geçersiz değiştirgenler: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "VariableGet betikte bulunamadı: "
@@ -13410,6 +13722,66 @@ msgid "VariableSet not found in script: "
msgstr "VariableSet betikte bulunamadı: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Yeniden Yükle"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Derinlik İndeksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Derinlik İndeksi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Sabit"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Sabit"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Sabit"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Sabit"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "GDNative İskelet Etkinleştirildi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek Düğümü"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Sahne Ağacı Düzenleme"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Kendi"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Düğümleri Kes"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "Özel düğüm _step() metoduna sahip değil, grafiği işleyemez."
@@ -13421,13 +13793,75 @@ msgstr ""
"_step()'ten geçersiz dönüş değeri, tam sayı (dizi çıkışı) ya da dize "
"(hatası) olmalı."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Çağrılar"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Sabitler"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Yerel Ekseni Kullan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Yerel Ekseni Kullan"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Eylem"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Görsel Betikte Ara"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Getir %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Çerçeveyi Taşı"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Fizik Kare %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Sinyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Sinyal"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Örnek"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14064,15 +14498,25 @@ msgstr ""
"çalışır."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GPU tabanlı parçacıklar GLES2 video sürücüsü tarafından desteklenmez.\n"
"Bunun yerine CPUParçacıklar2B düğümünü kullanın. Bu amaçla "
"\"CPUParçacıklar'a Dönüştür\" seçeneğini kullanabilirsiniz."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14327,10 +14771,11 @@ msgid "Only uniform scales are supported."
msgstr "Yalnızca tek tip ölçekler desteklenir."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GPU tabanlı parçacıklar GLES2 video sürücüsü tarafından desteklenmez.\n"
"Bunun yerine CPUParçacık düğümünü kullanın. Bu amaçla \"CPUParçacık'a "
@@ -14338,6 +14783,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Hiçbirşey görünebilir değil çünkü örüntüler çizim geçişlerine atanmış değil."
diff --git a/editor/translations/tt.po b/editor/translations/tt.po
index 5032eb753a..abbc0eed73 100644
--- a/editor/translations/tt.po
+++ b/editor/translations/tt.po
@@ -358,6 +358,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -807,6 +808,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -856,8 +858,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1880,7 +1881,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1997,7 +1997,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2165,7 +2166,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2195,6 +2196,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2888,7 +2891,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3023,10 +3026,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3243,6 +3242,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3319,7 +3319,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3544,6 +3543,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4399,6 +4403,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6042,6 +6047,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9324,7 +9330,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9332,7 +9338,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9340,7 +9351,36 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Җәмәгать"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9352,39 +9392,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9392,15 +9448,108 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+#, fuzzy
+msgid "Commit List"
+msgstr "Җәмәгать"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11909,6 +12058,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12737,6 +12887,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12749,6 +12931,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12765,6 +13021,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12774,6 +13042,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12782,6 +13054,54 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12791,12 +13111,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13358,7 +13730,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13571,7 +13952,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po
index 77ca1dae62..e83ce5dc02 100644
--- a/editor/translations/tzm.po
+++ b/editor/translations/tzm.po
@@ -356,6 +356,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -805,6 +806,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -854,8 +856,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1878,7 +1879,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -1995,7 +1995,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2163,7 +2164,7 @@ msgstr ""
msgid "Signal"
msgstr ""
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2193,6 +2194,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2886,7 +2889,7 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3021,10 +3024,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3241,6 +3240,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3317,7 +3317,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3542,6 +3541,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4397,6 +4401,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6040,6 +6045,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9322,7 +9328,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9330,7 +9336,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9338,7 +9349,35 @@ msgid "Commit"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+msgid "Staged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unstaged Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9350,39 +9389,55 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+msgid "Remote Login"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect new changes"
+msgid "Username"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
+msgid "Password"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "SSH Public Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
+msgid "Select SSH public key path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
+msgid "SSH Private Key Path"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Detect new changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
+msgid "Stage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+msgid "Unstage all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Message"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9390,15 +9445,107 @@ msgid "Commit Changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Commit List"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Create New Branch"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Remove Branch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remotes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Create New Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remove Remote"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Remote URL"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "View:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Split"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -11907,6 +12054,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -12735,6 +12883,38 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Condition"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -12747,6 +12927,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -12763,6 +13017,18 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Function"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -12772,6 +13038,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -12780,6 +13050,54 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Global Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Class Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Basic Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Math Constant"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Node"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Scene Tree"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "CustomNode"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -12789,12 +13107,64 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Construct %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Action %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr ""
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitNodeSignal"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13356,7 +13726,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13569,7 +13948,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 9ded993590..e1d0021c08 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -3,7 +3,7 @@
# Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Aleksandr <XpycT.TOP@gmail.com>, 2017.
-# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021.
+# Yuri Chornoivan <yurchor@ukr.net>, 2018, 2019, 2020, 2021, 2022.
# Ðндрій Бандура <andriykopanytsia@gmail.com>, 2018.
# Гидеон Теон <t.kudely94@gmail.com>, 2017.
# МакÑим Якимчук <xpinovo@gmail.com>, 2018, 2019.
@@ -22,7 +22,7 @@ msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-12-11 06:25+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -32,7 +32,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.10-dev\n"
+"X-Generator: Weblate 4.10.1\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -338,9 +338,8 @@ msgid "Duplicate Key(s)"
msgstr "Дублювати ключі"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "Додати %d кадри"
+msgstr "Додати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ RESET"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -377,6 +376,7 @@ msgstr "Створити %d нові доріжки Ñ– вÑтавити ключ
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -513,9 +513,8 @@ msgstr ""
"одинарна доріжка."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "МаÑÑˆÑ‚Ð°Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² анімації"
+msgstr "Додати RESET-ключові до анімації"
#: editor/animation_track_editor.cpp
msgid ""
@@ -848,6 +847,7 @@ msgstr "Додати"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -899,8 +899,7 @@ msgstr "Ðе вдалоÑÑ Ð·'єднати Ñигнал"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1503,7 +1502,7 @@ msgstr "Ðекоректна назва."
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "Ðе може починатиÑÑ Ð· цифри."
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1970,7 +1969,6 @@ msgid "New Folder..."
msgstr "Створити теку..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Оновити"
@@ -2087,7 +2085,8 @@ msgstr "Каталоги та файли:"
msgid "Preview:"
msgstr "Попередній переглÑд:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Файл:"
@@ -2137,9 +2136,8 @@ msgid "Properties"
msgstr "ВлаÑтивоÑті"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "перевизначеннÑ:"
+msgstr "Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2262,7 +2260,7 @@ msgstr "Метод"
msgid "Signal"
msgstr "Сигнал"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Сталий"
@@ -2279,20 +2277,24 @@ msgid "Property:"
msgstr "ВлаÑтивіÑть:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(значеннÑ)"
+msgstr "Пришпилити значеннÑ"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
msgstr ""
+"ÐŸÑ€Ð¸ÑˆÐ¿Ð¸Ð»ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð·Ð²ÐµÐ´Ðµ до примуÑового Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ, навіть "
+"Ñкщо воно дорівнює типовому."
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
+"Пришпилити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ [вимкнено, оÑкільки «%s» призначено лише Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Ð’Ñтановити %s"
@@ -2303,26 +2305,23 @@ msgstr "Ð’Ñтановити кратніÑть:"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "Пришпилено %s"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "Відшпилено %s"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
-msgstr "Копіювати влаÑтивоÑті"
+msgstr "Копіювати влаÑтивіÑть"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
-msgstr "Ð’Ñтавити влаÑтивоÑті"
+msgstr "Ð’Ñтавити влаÑтивіÑть"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "Копіювати шлÑÑ… до Ñкрипту"
+msgstr "Копіювати шлÑÑ… до влаÑтивоÑті"
#: editor/editor_log.cpp
msgid "Output:"
@@ -3051,8 +3050,9 @@ msgid "Install Android Build Template..."
msgstr "Ð’Ñтановити шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android…"
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних проєкту"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних редактора"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3142,7 +3142,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "ПримуÑово вÑтановити резерви Ð´Ð»Ñ ÑˆÐµÐ¹Ð´ÐµÑ€Ñ–Ð²"
#: editor/editor_node.cpp
msgid ""
@@ -3153,6 +3153,13 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"Якщо позначено цей пункт, шейдери буде викориÑтано у їхній резервній формі "
+"(або зроблено видимими через убершейдер чи приховано) протÑгом уÑього чаÑу "
+"роботи.\n"
+"Це кориÑно Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ виглÑду Ñ– швидкодіії резервних варіантів, Ñкі за "
+"звичайних умов буде показано дуже коротко.\n"
+"Щоб цей пункт запрацював, у параметрах проєкту має бути увімкнено аÑинхронну "
+"компілÑцію шейдерів."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3211,10 +3218,6 @@ msgid "Toggle Fullscreen"
msgstr "Перемикач повноекранного режиму"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Увімкнути або вимкнути конÑоль ÑиÑтеми"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних/параметрів редактора"
@@ -3445,6 +3448,7 @@ msgid "Load Errors"
msgstr "Помилки завантаженнÑ"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Виділити"
@@ -3521,7 +3525,6 @@ msgid "Author"
msgstr "Ðвтор"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "СтатуÑ"
@@ -3767,6 +3770,12 @@ msgstr "ШлÑÑ… до Ñцени:"
msgid "Import From Node:"
msgstr "Імпортувати з вузла:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Помилка"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "Відкрити теку, Ñка міÑтить ці шаблони."
@@ -4309,9 +4318,8 @@ msgid "Replace..."
msgstr "Замінити..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "Замінити вÑÑ–"
+msgstr "Замінити у файлах"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4322,9 +4330,8 @@ msgid "Replace: "
msgstr "Замінити: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "Замінити вÑÑ–"
+msgstr "Замінити вÑÑ– (БЕЗ СКÐСУВÐÐÐЯ)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4549,6 +4556,8 @@ msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
msgstr ""
+"Виберіть файл реÑурÑів у файловій ÑиÑтемі або у інÑпекторі Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ "
+"параметрів імпортуваннÑ."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4657,6 +4666,7 @@ msgid "Subfolder:"
msgstr "Підтека:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Ðвтор:"
@@ -6018,9 +6028,8 @@ msgid "Alt+Drag: Move selected node."
msgstr "Alt+ПеретÑгнути: переміÑтити позначений вузол."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+ПеретÑгнути: переміÑтити позначений вузол."
+msgstr "Alt+ПеретÑгнути: маÑштабувати позначений вузол."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
@@ -6054,7 +6063,7 @@ msgstr "Режим маÑштабуваннÑ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Shift: маÑштабувати пропорційно."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6153,9 +6162,8 @@ msgstr "Ð‘Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ об'єкта на міÑці (нÐ
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "Заблокувати позначене"
+msgstr "Заблокувати позначені вузли"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6164,9 +6172,8 @@ msgstr "Розблокувати вибраний об'єкт (можна пер
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "Розблокувати позначене"
+msgstr "Розблокувати позначені вузли"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6175,9 +6182,8 @@ msgstr "Гарантує нащадки об'єкта не можуть бути
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "Згрупувати позначені"
+msgstr "Згрупувати позначені вузли"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6186,9 +6192,8 @@ msgstr "Відновлює можливіÑть вибору нащадків о
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "Розгрупувати позначені"
+msgstr "Розгрупувати позначені вузли"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6361,6 +6366,7 @@ msgid "Zoom to 1600%"
msgstr "МаÑштаб у 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Додати %s"
@@ -7835,9 +7841,8 @@ msgid "Find in Files..."
msgstr "Знайти у файлах…"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "Замінити..."
+msgstr "Замінити у файлах…"
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -8365,16 +8370,15 @@ msgstr "ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð¾Ð³Ð»Ñду"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "Зменшити поле зору"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "Збільшити поле зору"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "ПовернутиÑÑ Ð´Ð¾ типового"
+msgstr "ПовернутиÑÑ Ð´Ð¾ типового Ð¿Ð¾Ð»Ñ Ð·Ð¾Ñ€Ñƒ"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -9105,22 +9109,19 @@ msgstr "Додати тип"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "Фільтрувати ÑпиÑок типів або Ñтворити неÑтандартний тип:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "ДоÑтупні профілі:"
+msgstr "ДоÑтупні типи на оÑнові вузлів:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° файла."
+msgstr "Ðазва типу Ñ” порожньою!"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "Ви Ñправді хочете відкрити декілька проєктів одразу?"
+msgstr "Ви Ñправді хочете Ñтворити порожній тип?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9747,7 +9748,8 @@ msgid "TileSet"
msgstr "Ðабір плиток"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Ðемає доÑтупних доданків ÑиÑтем ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9755,16 +9757,56 @@ msgid "Error"
msgstr "Помилка"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Ðе додано жодних файлів Ð´Ð»Ñ Ð²Ð½ÐµÑку"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Ім'Ñ Ð½Ðµ вказано."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "ВнеÑок"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Додаток ÑиÑтеми ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÑ€ÑÑ–Ñми не ініціалізовано"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Зміни шейдерів:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Зміни шейдерів:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "ВнеÑок"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Піддерево"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Ви Ñправді хочете Ñтворити порожній тип?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "ЗаÑтоÑувати ÑкиданнÑ"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9775,16 +9817,148 @@ msgid "Initialize"
msgstr "Ініціалізувати"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "ОблаÑть внеÑку"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Вилучити точку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Перейменувати"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "ВиÑвити зміни"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Зміни"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Закрити та зберегти зміни?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¸Ñ… змін..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Зміни матеріалу:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "ВнеÑти зміни"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "ВнеÑти зміни"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "ВнеÑок"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "Збіги:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "Створити новий проєкт"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Видалити доріжку"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "Віддалений"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Створити новий проєкт"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Вилучити елемент"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Віддалений "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Віддалений "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "Початкова Ñітка:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9803,29 +9977,23 @@ msgid "Typechange"
msgstr "Зміна типу"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "Вибрано Ð´Ð»Ñ Ð²Ð½ÐµÑку"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "ВнеÑти вÑе"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "ВнеÑти зміни"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr ""
-"ПереглÑнути відмінноÑті у файлах, перш ніж внеÑти Ñ—Ñ… до найÑвіжішої верÑÑ–Ñ—"
+#, fuzzy
+msgid "View:"
+msgstr "ПереглÑд"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "Ðемає активних відмінноÑтей між файлами"
+#, fuzzy
+msgid "Split"
+msgstr "Розділити шлÑÑ…"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "ВиÑвити зміни у відмінноÑÑ‚ÑÑ… між файлами"
+#, fuzzy
+msgid "Unified"
+msgstr "Змінено"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -11978,6 +12146,11 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ðе можна зберігати гілку, Ñка Ñ” дочірньою щодо Ñцени, Ñка вже має "
+"екземплÑÑ€.\n"
+"Щоб зберегти цю гілку до Ñ—Ñ— влаÑної Ñцени, відкрийте початкову Ñцену, "
+"клацніть правою кнопкою миші на Ñ—Ñ— гілці Ñ– виберіть «Зберегти гілку Ñк "
+"Ñцену»."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11985,6 +12158,10 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"Ðе можна зберігати гілку, Ñка Ñ” чаÑтиною уÑпадкованої Ñцени.\n"
+"Щоб зберегти цю гілку до Ñ—Ñ— влаÑної Ñцени, відкрийте початкову Ñцену, "
+"клацніть правою кнопкою миші на Ñ—Ñ— гілці Ñ– виберіть «Зберегти гілку Ñк "
+"Ñцену»."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -12524,6 +12701,7 @@ msgid "Export list to a CSV file"
msgstr "ЕкÑпортувати ÑпиÑок до файла CSV"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "ШлÑÑ… до реÑурÑу"
@@ -13372,6 +13550,40 @@ msgstr "Оновити граф"
msgid "Edit Member"
msgstr "Редагувати член"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Ð’Ñтановити вираз"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "анімаціÑ"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Тип вводу не ітерабельний: "
@@ -13384,6 +13596,88 @@ msgstr "Ітератор Ñтав недійÑним"
msgid "Iterator became invalid: "
msgstr "Ітератор Ñтав недійÑним: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÐ¸:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "Тон:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Типи:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Цей об'єкт"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Ðа Ñимволі %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Додати %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Ð’Ñтановити %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Пришпилено %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Отримати %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Ðеправильний Ñ–Ð½Ð´ÐµÐºÑ Ð²Ð»Ð°ÑтивоÑті імені."
@@ -13400,6 +13694,21 @@ msgstr "ШлÑÑ… не веде до вузла!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Ðекоректна назва влаÑтивоÑті індекÑу, «%s», у вузлі %s."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Ð’Ñтановити %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Функції"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Змінити розмір маÑиву"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Ðеправильний тип аргументу: "
@@ -13409,6 +13718,10 @@ msgid ": Invalid arguments: "
msgstr ": ÐеприпуÑтимі аргументи: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Ðе знайдено VariableGet у Ñкрипті: "
@@ -13417,6 +13730,66 @@ msgid "VariableSet not found in script: "
msgstr "Ðе знайдено VariableSet у Ñкрипті: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Перезавантажити"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z-індекÑ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z-індекÑ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Сталий"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Сталий"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Сталий"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Сталий"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Увімкнений одинак GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Вузол пошуку чаÑу"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ñ”Ñ€Ð°Ñ€Ñ…Ñ–Ñ— Ñцени"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Цей об'єкт"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Вирізати вузли"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "У нетиповому вузлі немає методу _step(). Обробка графу неможлива."
@@ -13428,13 +13801,75 @@ msgstr ""
"_step() повертає некоректне значеннÑ. ЗначеннÑм має бути ціле чиÑло (seq "
"out) або Ñ€Ñдок (error)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Виклики"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "КонÑтанти"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "ВикориÑтати локальний проÑтір"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "ВикориÑтати локальний проÑтір"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ДіÑ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Шукати VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Отримати %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "ПереÑунути кадр"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Фізичний кадр %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Сигнал"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "ЕкземплÑÑ€"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14061,13 +14496,15 @@ msgstr ""
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
-msgstr ""
+msgstr "NavigationAgent2D можна викориÑтовувати лише під вузлом Node2D."
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
"The NavigationObstacle2D only serves to provide collision avoidance to a "
"Node2D object."
msgstr ""
+"NavigationObstacle2D призначено лише Ð´Ð»Ñ Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ñобів ÑƒÐ½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½Ð½Ñ "
+"Ð´Ð»Ñ Ð¾Ð±'єкта Node2D."
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -14094,16 +14531,26 @@ msgstr ""
"ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"У драйвері GLES2 не передбачено підтримки чаÑток із обробкою за допомогою "
"графічного процеÑора.\n"
"Вам Ñлід ÑкориÑтатиÑÑ Ð²ÑƒÐ·Ð»Ð¾Ð¼ CPUParticles2D. Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ можете вибрати пункт "
"«Перетворити на CPUParticles»."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14332,7 +14779,7 @@ msgstr "SpotLight з кутом, Ñкий Ñ” більшим за 90 градуÑ
#: scene/3d/navigation_agent.cpp
msgid "The NavigationAgent can be used only under a spatial node."
-msgstr ""
+msgstr "NavigationAgent можна викориÑтовувати лише під проÑторовим вузлом."
#: scene/3d/navigation_mesh_instance.cpp
msgid ""
@@ -14347,6 +14794,8 @@ msgid ""
"The NavigationObstacle only serves to provide collision avoidance to a "
"spatial object."
msgstr ""
+"NavigationObstacle призначено лише Ð´Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð·Ð°Ñобів ÑƒÐ½Ð¸ÐºÐ½ÐµÐ½Ð½Ñ "
+"Ð·Ñ–Ñ‚ÐºÐ½ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñторового об'єкта."
#: scene/3d/occluder.cpp
msgid "No shape is set."
@@ -14357,10 +14806,11 @@ msgid "Only uniform scales are supported."
msgstr "Передбачено підтримку лише однорідних маÑштабів."
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"У драйвері GLES2 не передбачено підтримки чаÑток із обробкою за допомогою "
"графічного процеÑора.\n"
@@ -14369,6 +14819,14 @@ msgstr ""
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
"Ðічого не видно, оÑкільки Ñітки не було пов'Ñзано із проходами малюваннÑ."
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index c84931094f..a93f7f85b5 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -364,6 +364,7 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -819,6 +820,7 @@ msgstr ""
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -869,8 +871,7 @@ msgstr ".تمام کا انتخاب"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1917,7 +1918,6 @@ msgid "New Folder..."
msgstr ""
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr ""
@@ -2039,7 +2039,8 @@ msgstr ""
msgid "Preview:"
msgstr ""
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr ""
@@ -2212,7 +2213,7 @@ msgstr ""
msgid "Signal"
msgstr ".تمام کا انتخاب"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr ""
@@ -2243,6 +2244,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -2947,8 +2950,9 @@ msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr ""
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "سب سکریپشن بنائیں"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3083,10 +3087,6 @@ msgid "Toggle Fullscreen"
msgstr ""
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr ""
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr ""
@@ -3308,6 +3308,7 @@ msgid "Load Errors"
msgstr ""
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr ""
@@ -3386,7 +3387,6 @@ msgid "Author"
msgstr ""
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3615,6 +3615,11 @@ msgstr ""
msgid "Import From Node:"
msgstr ""
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+msgid "%s Error"
+msgstr ""
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4499,6 +4504,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr ""
@@ -6195,6 +6201,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -9613,7 +9620,7 @@ msgid "TileSet"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9621,7 +9628,12 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "No commit message was provided."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9630,7 +9642,38 @@ msgid "Commit"
msgstr "کمیونٹی"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "کمیونٹی"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Apply"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9642,7 +9685,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9651,51 +9724,139 @@ msgid "Detect new changes"
msgstr "سب سکریپشن بنائیں"
#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Discard all changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
-msgstr ".Ù†ÙˆÙ¹ÙØ¦Ø± Ú©Û’ اکسٹنٹ Ú©Ùˆ تبدیل کیجیۓ"
+msgid "Stage all changes"
+msgstr "سب سکریپشن بنائیں"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+msgid "Unstage all changes"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
+msgid "Commit Message"
+msgstr "کمیونٹی"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "کمیونٹی"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branches"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "سب سکریپشن بنائیں"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "انیم ٹریک Ûٹائیں"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
msgstr ".تمام کا انتخاب"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
+msgid "Create New Remote"
+msgstr "سب سکریپشن بنائیں"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Typechange"
+#, fuzzy
+msgid "Remove Remote"
+msgstr ".تمام کا انتخاب"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "ریموٹ "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "ریموٹ "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
+msgid "Renamed"
msgstr ".تمام کا انتخاب"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
+#, fuzzy
+msgid "Deleted"
+msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Typechange"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
+msgid "Unmerged"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "View:"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Split"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12257,6 +12418,7 @@ msgid "Export list to a CSV file"
msgstr ""
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13125,6 +13287,39 @@ msgstr ""
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13137,6 +13332,80 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "in order:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Subtract %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13153,6 +13422,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr ".تمام کا انتخاب"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13162,6 +13444,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13170,6 +13456,61 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "Preload"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "مستقل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "مستقل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "مستقل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "مستقل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr ".اینیمیشن کی کیز کو ڈیلیٹ کرو"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "سب سکریپشن بنائیں"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "ایکشن منتقل کریں"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13179,13 +13520,70 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "مستقل"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "ایکشن منتقل کریں"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "سب سکریپشن بنائیں"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "ایکشن منتقل کریں"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Next Physics Frame"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr ".تمام کا انتخاب"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr ".تمام کا انتخاب"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "WaitInstanceSignal"
msgstr ""
#: platform/android/export/export_plugin.cpp
@@ -13755,7 +14153,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -13968,7 +14375,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 1a7c450e3d..f9bec13fd9 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -376,6 +376,7 @@ msgstr "Tạo %d track mới và chèn key?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -842,6 +843,7 @@ msgstr "Thêm"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -892,8 +894,7 @@ msgstr "Không thể kết nối tín hiệu"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1954,7 +1955,6 @@ msgid "New Folder..."
msgstr "Thư mục mới ..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "Làm mới"
@@ -2071,7 +2071,8 @@ msgstr "Các Thư mục và Tệp tin:"
msgid "Preview:"
msgstr "Xem thá»­:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "Tệp tin:"
@@ -2250,7 +2251,7 @@ msgstr "Phương thức"
msgid "Signal"
msgstr "Tín hiệu"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "Hằng số"
@@ -2281,6 +2282,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "Gán %s"
@@ -3025,8 +3028,9 @@ msgid "Install Android Build Template..."
msgstr "Cài đặt mẫu xây dựng Android..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "Mở Thư mục dữ liệu cá»§a Dá»± Ãn"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "Mở thư mục dữ liệu của trình chỉnh sửa"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3174,10 +3178,6 @@ msgid "Toggle Fullscreen"
msgstr "Chế độ Toàn màn hình"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "Kích hoạt Console Hệ thống"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "Mở thư mục dữ liệu của trình chỉnh sửa"
@@ -3410,6 +3410,7 @@ msgid "Load Errors"
msgstr "Nạp Lỗi"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "Chá»n"
@@ -3489,7 +3490,6 @@ msgid "Author"
msgstr "Tác giả"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "Trạng thái"
@@ -3719,6 +3719,12 @@ msgstr "ÄÆ°á»ng dẫn Cảnh:"
msgid "Import From Node:"
msgstr "Nhập từ Nút:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "Lá»—i"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4628,6 +4634,7 @@ msgid "Subfolder:"
msgstr "Thư mục phụ:"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "Tác giả:"
@@ -6314,6 +6321,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "Thêm %s"
@@ -9770,7 +9778,8 @@ msgid "TileSet"
msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "Không có phần má»m kiểm soát phiên bản khả dụng."
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9778,8 +9787,14 @@ msgid "Error"
msgstr "Lá»—i"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "Không có tệp nào trong giai Ä‘oạn chá»"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "Không có tên được cung cấp."
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -9787,8 +9802,42 @@ msgid "Commit"
msgstr "Cộng đồng"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "Trình kiểm soát phiên bản chưa được khởi tạo"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "Những thay đổi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Những thay đổi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "Cộng đồng"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "Cây con"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "Bạn chắc chắn mở nhiá»u hÆ¡n má»™t dá»± án?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "Ãp dụng đặt lại"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9799,61 +9848,186 @@ msgid "Initialize"
msgstr "Khởi tạo"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "Vùng chá»"
+#, fuzzy
+msgid "Remote Login"
+msgstr "Xoá điểm"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "Äổi tên"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "Phát hiện thay đổi mới"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "Những thay đổi"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "Äóng và lưu thay đổi?"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
-msgstr "Äã sá»­a đổi"
+#, fuzzy
+msgid "Stage all changes"
+msgstr "Lưu các thay đổi cục bộ ..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Renamed"
-msgstr "Äã đổi tên"
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "Äối số đã thay đổi"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Deleted"
-msgstr "Äã Xóa"
+#, fuzzy
+msgid "Commit Message"
+msgstr "Äổi"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
+msgid "Commit Changes"
msgstr "Äổi"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "Xoá lá»±a chá»n"
+msgid "Commit List"
+msgstr "Cộng đồng"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "Chá»n Toàn Bá»™"
+msgid "Branches"
+msgstr "Phù hợp:"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "Äổi"
+msgid "Create New Branch"
+msgstr "Tạo mới Dự án"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "Xóa Anim Track"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "Kiểm tra các khác biệt trước khi xác nhận vào phiên bản mới nhất"
+#, fuzzy
+msgid "Remotes"
+msgstr "Xóa"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "Tạo mới Dự án"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "Gõ bỠMục"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "Tên Node:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "Xóa"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+#, fuzzy
+msgid "Force Push"
+msgstr "Lưới nguồn:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr "Äã sá»­a đổi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Renamed"
+msgstr "Äã đổi tên"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Deleted"
+msgstr "Äã Xóa"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "Äổi"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
msgstr ""
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "Hiện thị"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "Tách đưá»ng"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unified"
+msgstr "Äã sá»­a đổi"
+
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
msgstr "(Chỉ dành cho GLES3)"
@@ -12516,6 +12690,7 @@ msgid "Export list to a CSV file"
msgstr "Xuất hồ sơ"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "ÄÆ°á»ng dẫn Tài nguyên"
@@ -13370,6 +13545,40 @@ msgstr "Làm mới đồ thị"
msgid "Edit Member"
msgstr ""
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "Äặt phép diá»…n đạt"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "Hoạt ảnh"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "Kiểu đầu vào không lặp được: "
@@ -13382,6 +13591,87 @@ msgstr "TrỠlặp không còn hợp lệ"
msgid "Iterator became invalid: "
msgstr "TrỠlặp không còn hợp lệ: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "Äổi tên thư mục:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "Kiểu:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "Chính nó"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "Tại kí tự %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "Thêm %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "Gán %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "Thêm %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "Lấy %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "Tên thuộc tính chỉ mục không hợp lệ."
@@ -13398,6 +13688,21 @@ msgstr "ÄÆ°á»ng dẫn không chỉ đến Nút!"
msgid "Invalid index property name '%s' in node %s."
msgstr "Tên thuộc tính chỉ mục '%s' ở nút '%s' không hợp lệ."
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "Gán %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "Hàm"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "Thay đổi kích thước mảng"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": Tham số có loại không hợp lệ: "
@@ -13407,6 +13712,10 @@ msgid ": Invalid arguments: "
msgstr ": Tham số không hợp lệ: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "Không tìm thấy VariableGet trong tệp lệnh: "
@@ -13416,6 +13725,66 @@ msgid "VariableSet not found in script: "
msgstr "Không tìm thấy VariableSet trong tệp lệnh: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "Tải lại"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Chỉ số Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Chỉ số Z"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "Hằng số"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "Hằng số"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "Hằng số"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "Hằng số"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "Bật đơn nhất GDNative"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "Nút TimeSeek"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "Chỉnh sửa cảnh"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "Chính nó"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "Cắt các nút"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "Nút tùy chá»n không có phương thức _step(), không thể xá»­ lí đồ thị."
@@ -13428,13 +13797,75 @@ msgstr ""
"_step() trả giá trị không hợp lệ, phải là số nguyên (seq out), hoặc xâu "
"(lá»—i)."
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "Lượt gá»i"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "Hằng số"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "Sử dụng Không gian Cục bộ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "Sử dụng Không gian Cục bộ"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "Chá»n tất cả"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "Tìm VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "Lấy %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "Di chuyển Khung hình"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "Khung hình Vật lý %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "Tín hiệu"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "Tín hiệu"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Thêm vào Cảnh"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -14067,15 +14498,25 @@ msgstr ""
"Nút ParallaxLayer chỉ hoạt động khi là con của một nút ParallaxBackground."
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"Video driver GLES2 không hỗ trợ hạt dựa trên bộ xử lí GPU.\n"
"Thay vào đó hãy dùng nút CPUParticles2D. Bạn có thể dùng tùy chá»n \"Chuyển "
"thành CPUParticles\" cho mục đích này."
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -14310,10 +14751,22 @@ msgid "Only uniform scales are supported."
msgstr ""
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+"Video driver GLES2 không hỗ trợ hạt dựa trên bộ xử lí GPU.\n"
+"Thay vào đó hãy dùng nút CPUParticles2D. Bạn có thể dùng tùy chá»n \"Chuyển "
+"thành CPUParticles\" cho mục đích này."
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 06fe826028..314cc33f9f 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -58,7 +58,7 @@
# idleman <1524328475@qq.com>, 2019.
# king <wangding1992@126.com>, 2019.
# silentbird <silentbird520@outlook.com>, 2019.
-# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021.
+# Haoyu Qiu <timothyqiu32@gmail.com>, 2019, 2020, 2021, 2022.
# Revan Ji <jiruifancr@gmail.com>, 2020.
# nieyuanhong <15625988003@163.com>, 2020.
# binotaliu <binota@protonmail.ch>, 2020.
@@ -88,7 +88,7 @@ msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2021-12-31 08:52+0000\n"
+"PO-Revision-Date: 2022-01-12 16:52+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"
@@ -106,7 +106,7 @@ msgstr "convert() çš„å‚æ•°ç±»åž‹æ— æ•ˆï¼Œè¯·ä½¿ç”¨ TYPE_* 常é‡ã€‚"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "应为长度为 1 的字符串(1个字符)。"
+msgstr "应为长度为 1 的字符串(å•个字符)。"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -399,9 +399,8 @@ msgid "Duplicate Key(s)"
msgstr "å¤åˆ¶å…³é”®å¸§"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add RESET Value(s)"
-msgstr "添加 %d 帧"
+msgstr "添加 RESET 值"
#: editor/animation_track_editor.cpp
msgid "Delete Key(s)"
@@ -438,6 +437,7 @@ msgstr "æ˜¯å¦æ–°å»º %d 个轨é“å¹¶æ’入关键帧?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -521,11 +521,11 @@ msgstr "添加è´å¡žå°”轨é“"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr "轨é“路径无效,因此无法添加键。"
+msgstr "轨é“路径无效,因此无法添加关键帧。"
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
-msgstr "轨é“䏿˜¯ Spatial 类型,无法æ’入帧"
+msgstr "轨é“䏿˜¯ Spatial 类型,无法æ’入关键帧"
#: editor/animation_track_editor.cpp
msgid "Add Transform Track Key"
@@ -570,9 +570,8 @@ msgid ""
msgstr "ç”±äºŽåªæœ‰å•一轨é“,因此该选项ä¸é€‚用于è´å¡žå°”编辑。"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Add RESET Keys"
-msgstr "缩放动画关键帧"
+msgstr "添加动画 RESET 关键帧"
#: editor/animation_track_editor.cpp
msgid ""
@@ -898,6 +897,7 @@ msgstr "添加"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -947,8 +947,7 @@ msgstr "无法连接信å·"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1386,15 +1385,15 @@ 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"
@@ -1410,7 +1409,7 @@ msgstr "移动总线效果"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr "删除音频总线效果"
+msgstr "删除总线效果"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
@@ -1455,7 +1454,7 @@ msgstr "添加音频总线"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr "ä¸èƒ½åˆ é™¤ä¸»éŸ³é¢‘总线ï¼"
+msgstr "ä¸èƒ½åˆ é™¤ä¸»æ€»çº¿ï¼"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
@@ -1545,7 +1544,7 @@ msgstr "å称无效。"
#: editor/editor_autoload_settings.cpp
msgid "Cannot begin with a digit."
-msgstr ""
+msgstr "无法以数字开头。"
#: editor/editor_autoload_settings.cpp
msgid "Valid characters:"
@@ -1990,7 +1989,6 @@ msgid "New Folder..."
msgstr "新建文件夹..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "刷新"
@@ -2107,7 +2105,8 @@ msgstr "目录与文件:"
msgid "Preview:"
msgstr "预览:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "文件:"
@@ -2155,9 +2154,8 @@ msgid "Properties"
msgstr "属性"
#: editor/editor_help.cpp
-#, fuzzy
msgid "overrides %s:"
-msgstr "覆盖:"
+msgstr "覆盖 %s:"
#: editor/editor_help.cpp
msgid "default:"
@@ -2280,7 +2278,7 @@ msgstr "方法"
msgid "Signal"
msgstr "ä¿¡å·"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "常é‡"
@@ -2297,20 +2295,21 @@ msgid "Property:"
msgstr "属性:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Pin value"
-msgstr "(值)"
+msgstr "固定值"
#: editor/editor_inspector.cpp
msgid ""
"Pinning a value forces it to be saved even if it's equal to the default."
-msgstr ""
+msgstr "将值固定会强制ä¿å­˜è¿™ä¸ªå€¼ï¼Œå³ä¾¿å®ƒä¸Žé»˜è®¤å€¼ç›¸ç­‰ã€‚"
#: editor/editor_inspector.cpp
msgid "Pin value [Disabled because '%s' is editor-only]"
-msgstr ""
+msgstr "固定值 [å·²ç¦ç”¨ï¼Œå› ä¸ºâ€œ%sâ€ä»…适用于编辑器]"
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "设置 %s"
@@ -2321,26 +2320,23 @@ msgstr "批é‡è®¾ç½®ï¼š"
#: editor/editor_inspector.cpp
msgid "Pinned %s"
-msgstr ""
+msgstr "将 %s 固定"
#: editor/editor_inspector.cpp
msgid "Unpinned %s"
-msgstr ""
+msgstr "将 %s 解除固定"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property"
msgstr "å¤åˆ¶å±žæ€§"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Paste Property"
msgstr "粘贴属性"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Copy Property Path"
-msgstr "å¤åˆ¶è„šæœ¬è·¯å¾„"
+msgstr "å¤åˆ¶å±žæ€§è·¯å¾„"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2932,7 +2928,7 @@ msgstr "切æ¢ä¸“注模å¼ã€‚"
#: editor/editor_node.cpp
msgid "Add a new scene."
-msgstr "添加场景。"
+msgstr "添加新场景。"
#: editor/editor_node.cpp
msgid "Scene"
@@ -3038,8 +3034,9 @@ msgid "Install Android Build Template..."
msgstr "安装 Android 构建模æ¿..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "æ‰“å¼€é¡¹ç›®æ•°æ®æ–‡ä»¶å¤¹"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "打开 “编辑器数æ®â€ 文件夹"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3120,7 +3117,7 @@ msgstr "å¯ç”¨è¯¥é€‰é¡¹æ—¶ï¼Œå¯¼èˆªç½‘格和多边形将在项目è¿è¡Œæ—¶å¯è§
#: editor/editor_node.cpp
msgid "Force Shader Fallbacks"
-msgstr ""
+msgstr "强制备用ç€è‰²å™¨"
#: editor/editor_node.cpp
msgid ""
@@ -3131,6 +3128,10 @@ msgid ""
"Asynchronous shader compilation must be enabled in the project settings for "
"this option to make a difference."
msgstr ""
+"å¯ç”¨è¯¥é€‰é¡¹æ—¶ï¼Œç€è‰²å™¨åœ¨è¿è¡Œæ—¶ä¼šä½¿ç”¨å…¶å¤‡ç”¨å½¢å¼ï¼ˆå€ŸåŠ©è¶…çº§ç€è‰²å™¨æ˜¾ç¤ºæˆ–è€…ä¸æ˜¾"
+"示)。\n"
+"å¯ç”¨äºŽéªŒè¯å¤‡ç”¨å¤–观和性能,正常情况下åªä¼šçŸ­æš‚显示。\n"
+"必须在项目设置中å¯ç”¨å¼‚æ­¥ç€è‰²å™¨ç¼–译,该选项æ‰ä¼šæœ‰æ•ˆæžœã€‚"
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
@@ -3185,10 +3186,6 @@ msgid "Toggle Fullscreen"
msgstr "切æ¢å…¨å±æ¨¡å¼"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "打开ï¼å…³é—­ç³»ç»Ÿå‘½ä»¤è¡Œ"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "打开 “编辑器数æ®/设置†文件夹"
@@ -3415,6 +3412,7 @@ msgid "Load Errors"
msgstr "加载错误"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "选择"
@@ -3491,7 +3489,6 @@ msgid "Author"
msgstr "作者"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "状æ€"
@@ -3727,6 +3724,12 @@ msgstr "场景路径:"
msgid "Import From Node:"
msgstr "从节点中导入:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "错误"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "打开包å«è¿™äº›æ¨¡æ¿çš„æ–‡ä»¶å¤¹ã€‚"
@@ -4254,9 +4257,8 @@ msgid "Replace..."
msgstr "替æ¢..."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Replace in Files"
-msgstr "全部替æ¢"
+msgstr "在文件中替æ¢"
#: editor/find_in_files.cpp
msgid "Find: "
@@ -4267,9 +4269,8 @@ msgid "Replace: "
msgstr "替æ¢ï¼š "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace All (NO UNDO)"
-msgstr "全部替æ¢"
+msgstr "全部替æ¢ï¼ˆæ— æ³•撤销)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4489,7 +4490,7 @@ msgstr "警告:存在使用本资æºçš„ç´ æï¼Œå°†ä¼šåœæ­¢åŠ è½½ã€‚"
msgid ""
"Select a resource file in the filesystem or in the inspector to adjust "
"import settings."
-msgstr ""
+msgstr "è¦è°ƒæ•´å¯¼å…¥è®¾ç½®ï¼Œè¯·åœ¨æ–‡ä»¶ç³»ç»Ÿæˆ–æ£€æŸ¥å™¨ä¸­é€‰ä¸­èµ„æºæ–‡ä»¶ã€‚"
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4598,6 +4599,7 @@ msgid "Subfolder:"
msgstr "å­æ–‡ä»¶å¤¹ï¼š"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "作者:"
@@ -5694,7 +5696,7 @@ msgstr "创建垂直水平å‚考线"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
-msgstr "å°† CanvasItem“%sâ€çš„ Pivot Offset 设为 (%d, %d)"
+msgstr "å°† CanvasItem“%sâ€çš„轴心åç§»é‡è®¾ä¸º (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotate %d CanvasItems"
@@ -5922,20 +5924,19 @@ msgstr "选择模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Drag: Rotate selected node around pivot."
-msgstr "拖动:围绕中心点旋转所选节点。"
+msgstr "拖动:围绕轴心旋转所选节点。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move selected node."
msgstr "Alt+拖动:移动所选节点。"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Alt+Drag: Scale selected node."
-msgstr "Alt+拖动:移动所选节点。"
+msgstr "Alt+拖动:缩放所选节点。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "V: Set selected node's pivot position."
-msgstr "V:设置所选节点的中心点ä½ç½®ã€‚"
+msgstr "V:设置所选节点的轴心ä½ç½®ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5963,7 +5964,7 @@ msgstr "缩放模å¼"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Shift: Scale proportionally."
-msgstr ""
+msgstr "Shift:按比例缩放。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5976,7 +5977,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Click to change object's rotation pivot."
-msgstr "点击设置对象的旋转中心。"
+msgstr "点击更改对象的旋转轴心。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan Mode"
@@ -6062,9 +6063,8 @@ msgstr "将所选对象é”定到该ä½ç½®ï¼ˆæ— æ³•移动)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected Node(s)"
-msgstr "é”定所选项"
+msgstr "é”定所选节点"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6073,9 +6073,8 @@ msgstr "è§£é”æ‰€é€‰å¯¹è±¡ï¼ˆå¯ä»¥ç§»åŠ¨ï¼‰ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Unlock Selected Node(s)"
-msgstr "è§£é”æ‰€é€‰é¡¹"
+msgstr "è§£é”æ‰€é€‰èŠ‚ç‚¹"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6084,9 +6083,8 @@ msgstr "ç¡®ä¿å¯¹è±¡çš„å­é¡¹ä¸å¯é€‰æ‹©ã€‚"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected Node(s)"
-msgstr "编组所选项"
+msgstr "编组所选节点"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6095,9 +6093,8 @@ msgstr "æ¢å¤é€‰æ‹©å¯¹è±¡çš„å­çº§çš„功能。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected Node(s)"
-msgstr "解组所选项"
+msgstr "解组所选节点"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -6268,6 +6265,7 @@ msgid "Zoom to 1600%"
msgstr "缩放至 1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "添加 %s"
@@ -7291,7 +7289,7 @@ msgstr "翻转入å£"
#: editor/plugins/room_manager_editor_plugin.cpp
msgid "Occluder Set Transform"
-msgstr "鮿Œ¡é›†å˜æ¢"
+msgstr "鮿Œ¡è®¾ç½®å˜æ¢"
#: editor/plugins/room_manager_editor_plugin.cpp
msgid "Center Node"
@@ -7388,7 +7386,7 @@ msgstr "主题å¦å­˜ä¸º..."
#: editor/plugins/script_editor_plugin.cpp
msgid "%s Class Reference"
-msgstr "%s ç±»å‚考手册"
+msgstr "%s ç±»å‚考"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
@@ -7541,7 +7539,7 @@ msgstr "打开 Godot 在线文档。"
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
-msgstr "æœç´¢æ–‡æ¡£ã€‚"
+msgstr "æœç´¢å‚考文档。"
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to previous edited document."
@@ -7722,9 +7720,8 @@ msgid "Find in Files..."
msgstr "在文件中查找..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Replace in Files..."
-msgstr "替æ¢..."
+msgstr "在文件中替æ¢..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
@@ -7785,7 +7782,7 @@ msgstr "ç€è‰²å™¨"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "This skeleton has no bones, create some children Bone2D nodes."
-msgstr "该骨架没有骨骼绑定,请创建一些 Bone2D 骨骼å­èŠ‚ç‚¹ã€‚"
+msgstr "该骨架没有骨骼,请创建一些 Bone2D å­èŠ‚ç‚¹ã€‚"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Rest Pose to Bones"
@@ -7797,7 +7794,7 @@ msgstr "从骨骼创建放æ¾å§¿åŠ¿"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Skeleton2D"
-msgstr "2D 骨骼节点"
+msgstr "Skeleton2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Reset to Rest Pose"
@@ -7813,7 +7810,7 @@ msgstr "创建物ç†éª¨éª¼"
#: editor/plugins/skeleton_editor_plugin.cpp
msgid "Skeleton"
-msgstr "骨架"
+msgstr "Skeleton"
#: editor/plugins/skeleton_editor_plugin.cpp
msgid "Create physical skeleton"
@@ -7942,7 +7939,7 @@ msgstr "旋转 %s 度。"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Keying is disabled (no key inserted)."
-msgstr "键控被ç¦ç”¨ï¼ˆæœªæ’入键)。"
+msgstr "å·²ç¦ç”¨å…³é”®å¸§æ’入(未æ’入关键帧)。"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Animation Key Inserted."
@@ -8249,16 +8246,15 @@ msgstr "切æ¢è‡ªç”±è§‚看"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Decrease Field of View"
-msgstr ""
+msgstr "å‡å°è§†é‡Ž"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Increase Field of View"
-msgstr ""
+msgstr "增大视野"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Reset Field of View to Default"
-msgstr "é‡ç½®ä¸ºé»˜è®¤å€¼"
+msgstr "é‡ç½®ä¸ºé»˜è®¤è§†é‡Ž"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -8460,7 +8456,7 @@ msgstr "创建 LightOccluder2D 兄弟节点"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
-msgstr "ç²¾çµ"
+msgstr "Sprite"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
@@ -8983,22 +8979,19 @@ msgstr "添加类型"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Filter the list of types or create a new custom type:"
-msgstr ""
+msgstr "过滤类型列表或新建自定义类型:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Available Node-based types:"
-msgstr "å¯ç”¨é…置文件:"
+msgstr "å¯ç”¨ Node 类型:"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Type name is empty!"
-msgstr "文件å为空。"
+msgstr "类型å称为空ï¼"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Are you sure you want to create an empty type?"
-msgstr "æ‚¨ç¡®å®šè¦æ‰“开多个项目å—?"
+msgstr "确定è¦åˆ›å»ºç©ºç±»åž‹å—?"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Confirm Item Rename"
@@ -9609,7 +9602,8 @@ msgid "TileSet"
msgstr "图å—集"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "没有å¯ç”¨çš„ VCS æ’件。"
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9617,16 +9611,56 @@ msgid "Error"
msgstr "错误"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "没有文件被添加到暂存区"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "没有æä¾›å称。"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "æäº¤"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS æ’件未åˆå§‹åŒ–"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "ç€è‰²å™¨å˜æ›´ï¼š"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "ç€è‰²å™¨å˜æ›´ï¼š"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "æäº¤"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "å­æ ‘"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "确定è¦åˆ›å»ºç©ºç±»åž‹å—?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "应用é‡ç½®"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9637,16 +9671,148 @@ msgid "Initialize"
msgstr "åˆå§‹åŒ–"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "暂存区域"
+#, fuzzy
+msgid "Remote Login"
+msgstr "移除点"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "é‡å‘½å"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "检测新å˜åŒ–"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "修改"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "关闭并ä¿å­˜æ›´æ”¹å—?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "ä¿å­˜æœ¬åœ°æ›´æ”¹..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "æè´¨å˜æ›´ï¼š"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "æäº¤å˜æ›´"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "æäº¤å˜æ›´"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "æäº¤"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "匹é…项:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "新建项目"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "移除动画轨é“"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "远程"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "新建项目"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "移除项目"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "远程 "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "远程 "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "æºç½‘格:"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9665,28 +9831,23 @@ msgid "Typechange"
msgstr "类型更改"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "将选定放入暂存区"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "暂存全部"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "æäº¤å˜æ›´"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "在æäº¤åˆ°æœ€æ–°ç‰ˆæœ¬ä¹‹å‰æŸ¥çœ‹æ–‡ä»¶å·®å¼‚"
+#, fuzzy
+msgid "View:"
+msgstr "视图"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "没有文件差异处于活动状æ€"
+#, fuzzy
+msgid "Split"
+msgstr "拆分路径"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "检测文件差异的å˜åŒ–"
+#, fuzzy
+msgid "Unified"
+msgstr "已修改"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -9883,15 +10044,15 @@ msgstr "è¿”å›žä¸¤ä¸ªå‚æ•°ä¹‹é—´ %s 比较的布尔结果。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
-msgstr "等于 (==)"
+msgstr "等于(==)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than (>)"
-msgstr "大于 (>)"
+msgstr "大于(>)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than or Equal (>=)"
-msgstr "大于或等于 (>=)"
+msgstr "大于等于(>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9913,15 +10074,15 @@ msgstr "返回 NaN 和标é‡å‚数之间比较的布尔结果。"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than (<)"
-msgstr "å°äºŽ (<)"
+msgstr "å°äºŽï¼ˆ<)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than or Equal (<=)"
-msgstr "å°äºŽæˆ–等于 (<=)"
+msgstr "å°äºŽç­‰äºŽï¼ˆ<=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Not Equal (!=)"
-msgstr "ä¸ç­‰äºŽ (!=)"
+msgstr "ä¸ç­‰äºŽï¼ˆ!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -10525,7 +10686,7 @@ msgstr "(仅é™ç‰‡æ®µ/光照模å¼ï¼‰ï¼ˆæ ‡é‡ï¼‰â€œx†和 “y†中的ç»
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
-msgstr "å¯è§†ç€è‰²å™¨"
+msgstr "VisualShader"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Edit Visual Property:"
@@ -11766,6 +11927,9 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"无法ä¿å­˜åˆ†æ”¯ï¼Œè¯¥åˆ†æ”¯æ˜¯å®žä¾‹åŒ–场景的å­é¡¹ã€‚\n"
+"如果è¦å°†è¯¥åˆ†æ”¯ä¿å­˜ä¸ºå•独的场景,请先打开原始场景,å³é”®å•击该分支,然åŽé€‰æ‹©â€œå°†"
+"分支ä¿å­˜ä¸ºåœºæ™¯â€ã€‚"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11773,6 +11937,9 @@ msgid ""
"To save this branch into its own scene, open the original scene, right click "
"on this branch, and select \"Save Branch as Scene\"."
msgstr ""
+"无法ä¿å­˜åˆ†æ”¯ï¼Œè¯¥åˆ†æ”¯æ˜¯ç»§æ‰¿åœºæ™¯çš„å­é¡¹ã€‚\n"
+"如果è¦å°†è¯¥åˆ†æ”¯ä¿å­˜ä¸ºå•独的场景,请先打开原始场景,å³é”®å•击该分支,然åŽé€‰æ‹©â€œå°†"
+"分支ä¿å­˜ä¸ºåœºæ™¯â€ã€‚"
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
@@ -12299,6 +12466,7 @@ msgid "Export list to a CSV file"
msgstr "将列表导出为 CSV 文件"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "资æºè·¯å¾„"
@@ -12696,11 +12864,11 @@ msgstr "生æˆç¼“冲区"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Direct lighting"
-msgstr "直接照明"
+msgstr "直接光照"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Indirect lighting"
-msgstr "间接照明"
+msgstr "间接光照"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Post processing"
@@ -12937,19 +13105,19 @@ 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 键放置一个通用签å。"
+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 键放置一个通用签å。"
+msgstr "æŒ‰ä½ Ctrl 键放置 Getter èŠ‚ç‚¹ã€‚æŒ‰ä½ Shift 键放置通用签å。"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a simple reference to the node."
-msgstr "æŒ‰ä½ %s 放置一个场景节点的引用节点。"
+msgstr "æŒ‰ä½ %s 放置该节点的简å•引用。"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a simple reference to the node."
-msgstr "æŒ‰ä½ Ctrl 键放置一个场景节点的引用节点。"
+msgstr "æŒ‰ä½ Ctrl 键放置该节点的简å•引用。"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Variable Setter."
@@ -13131,6 +13299,40 @@ msgstr "刷新节点"
msgid "Edit Member"
msgstr "编辑æˆå‘˜"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "设置表达å¼"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "动画"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "输入类型ä¸å¯è¿­ä»£ï¼š "
@@ -13143,6 +13345,88 @@ msgstr "迭代器失效"
msgid "Iterator became invalid: "
msgstr "迭代器失效: "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "é‡å‘½å文件夹:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "俯仰角:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "类型:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "仅自己"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "ä½äºŽå­—符 %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "添加 %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "设置 %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "将 %s 固定"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "èŽ·å– %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "属性å称索引无效。"
@@ -13159,6 +13443,21 @@ msgstr "路径必须指å‘节点ï¼"
msgid "Invalid index property name '%s' in node %s."
msgstr "节点 “%s†的索引属性å “%s†无效。"
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "设置 %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "函数"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "调整数组大å°"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": æ— æ•ˆå‚æ•°ç±»åž‹: "
@@ -13168,6 +13467,10 @@ msgid ": Invalid arguments: "
msgstr ": æ— æ•ˆå‚æ•°: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "脚本中未找到 VariableGet: "
@@ -13176,6 +13479,66 @@ msgid "VariableSet not found in script: "
msgstr "脚本中未找到 VariableSet: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "釿–°åŠ è½½"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z 索引"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z 索引"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "常é‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "常é‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "常é‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "常é‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "å¯ç”¨çš„ GDNative å•例"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek 节点"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "场景树编辑"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "仅自己"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "剪切节点"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "自定义节点ä¸åŒ…å« _step() 方法,ä¸èƒ½ç”Ÿæˆå›¾åƒã€‚"
@@ -13185,13 +13548,75 @@ msgid ""
"(error)."
msgstr "_step() 的返回值无效,必须是整形 (Seq Out) 或字符串 (Error)。"
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "调用"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "常é‡"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "使用本地空间"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "使用本地空间"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "动作"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
-msgstr "æœç´¢å¯è§†åŒ–脚本节点"
+msgstr "æœç´¢ VisualScript"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "èŽ·å– %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "移动帧"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "物ç†å¸§ %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "ä¿¡å·"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "ä¿¡å·"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "实例化"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13756,13 +14181,13 @@ msgstr "æ­¤é®å…‰ä½“çš„é®å…‰å¤šè¾¹å½¢ä¸ºç©ºã€‚请绘制一个多边形。"
#: scene/2d/navigation_agent_2d.cpp
msgid "The NavigationAgent2D can be used only under a Node2D node."
-msgstr ""
+msgstr "NavigationAgent2D åªèƒ½åœ¨ Node2D 节点下使用。"
#: scene/2d/navigation_obstacle_2d.cpp
msgid ""
"The NavigationObstacle2D only serves to provide collision avoidance to a "
"Node2D object."
-msgstr ""
+msgstr "NavigationObstacle2D åªèƒ½ç”¨äºŽä¸º Node2D 对象é¿å…碰撞。"
#: scene/2d/navigation_polygon.cpp
msgid ""
@@ -13786,14 +14211,24 @@ msgstr ""
"ParallaxLayer 类型的节点必须作为 ParallaxBackground çš„å­èŠ‚ç‚¹æ‰èƒ½æ­£å¸¸å·¥ä½œã€‚"
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"基于 GPU 的粒å­ä¸å— GLES2 视频驱动程åºçš„æ”¯æŒã€‚\n"
"改为使用 CPUParticles2D 节点。为此,å¯ä»¥ä½¿ç”¨ “转æ¢ä¸º CPUParticles†选项。"
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -13981,7 +14416,7 @@ msgid ""
"GIProbes are not supported by the GLES2 video driver.\n"
"Use a BakedLightmap instead."
msgstr ""
-"GLES2 视频驱动程åºä¸æ”¯æŒ GIProbes。\n"
+"GLES2 视频驱动程åºä¸æ”¯æŒ GIProbe。\n"
"请改用 BakedLightmap。"
#: scene/3d/gi_probe.cpp
@@ -13999,7 +14434,7 @@ msgstr "角度宽于 90 度的 SpotLight 无法投射出阴影。"
#: scene/3d/navigation_agent.cpp
msgid "The NavigationAgent can be used only under a spatial node."
-msgstr ""
+msgstr "NavigationAgent åªèƒ½åœ¨ Spatial 节点下使用。"
#: scene/3d/navigation_mesh_instance.cpp
msgid ""
@@ -14013,7 +14448,7 @@ msgstr ""
msgid ""
"The NavigationObstacle only serves to provide collision avoidance to a "
"spatial object."
-msgstr ""
+msgstr "NavigationObstacle åªèƒ½ç”¨äºŽä¸º Spatial 对象é¿å…碰撞。"
#: scene/3d/occluder.cpp
msgid "No shape is set."
@@ -14024,16 +14459,25 @@ msgid "Only uniform scales are supported."
msgstr "仅支æŒç»Ÿä¸€çš„缩放。"
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"基于 GPU 的粒å­ä¸å— GLES2 视频驱动程åºçš„æ”¯æŒã€‚\n"
"改为使用 CPUParticles 节点。为此,您å¯ä»¥ä½¿ç”¨ “转æ¢ä¸º CPUParticles†选项。"
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "ç²’å­ä¸å¯è§ï¼Œå› ä¸ºæ²¡æœ‰ç½‘æ ¼æŒ‡å®šåˆ°ç»˜åˆ¶é€šé“ (Draw Pass)。"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index e9cd6f0e5f..a6ee771fa8 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -383,6 +383,7 @@ msgstr "新增 %d 個新軌跡並æ’入關éµå¹€ï¼Ÿ"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -870,6 +871,7 @@ msgstr "添加"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -919,8 +921,7 @@ msgstr "無法連接訊號"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -2016,7 +2017,6 @@ msgid "New Folder..."
msgstr "新增資料夾"
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "釿–°æ•´ç†"
@@ -2141,7 +2141,8 @@ msgstr "資料夾和檔案:"
msgid "Preview:"
msgstr "é è¦½:"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "檔案:"
@@ -2325,7 +2326,7 @@ msgstr ""
msgid "Signal"
msgstr "訊號"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "常數"
@@ -2355,6 +2356,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr ""
@@ -3100,7 +3103,7 @@ msgstr ""
#: editor/editor_node.cpp
#, fuzzy
-msgid "Open Project Data Folder"
+msgid "Open User Data Folder"
msgstr "開啟 Project Manager?"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
@@ -3244,11 +3247,6 @@ msgstr "全螢幕"
#: editor/editor_node.cpp
#, fuzzy
-msgid "Toggle System Console"
-msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件"
-
-#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
msgstr "編輯器設定"
@@ -3480,6 +3478,7 @@ msgid "Load Errors"
msgstr "載入錯誤"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "é¸å–"
@@ -3567,7 +3566,6 @@ msgid "Author"
msgstr "作者"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr ""
@@ -3801,6 +3799,12 @@ msgstr "場景路徑:"
msgid "Import From Node:"
msgstr "從Node導入:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "錯誤!"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr ""
@@ -4751,6 +4755,7 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Author:"
msgstr "作者:"
@@ -6523,6 +6528,7 @@ msgid "Zoom to 1600%"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr ""
@@ -10068,7 +10074,7 @@ msgid "TileSet"
msgstr "TileSet..."
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+msgid "No VCS plugins are available."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10076,19 +10082,57 @@ msgid "Error"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
+msgid "No commit message was provided."
+msgstr "沒有æä¾›å字。"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
msgid "Commit"
msgstr "社群"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "當改變時更新"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "當改變時更新"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "社群"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Subtitle:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s remote?"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "é‡è¨­ç¸®æ”¾æ¯”例"
+
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
msgstr ""
@@ -10097,7 +10141,37 @@ msgid "Initialize"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
+#, fuzzy
+msgid "Remote Login"
+msgstr "åªé™é¸ä¸­"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "釿–°å‘½å"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
@@ -10107,53 +10181,145 @@ msgstr "新增"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Changes"
+msgid "Discard all changes"
+msgstr "è¦é—œé–‰å ´æ™¯å—Žï¼Ÿï¼ˆæœªå„²å­˜çš„æ›´æ”¹å°‡æœƒæ¶ˆå¤±ï¼‰"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "儲存本地更改..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
msgstr "當改變時更新"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Modified"
+#, fuzzy
+msgid "Commit Message"
+msgstr "åŒæ­¥æ›´æ–°è…³æœ¬"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Changes"
+msgstr "åŒæ­¥æ›´æ–°è…³æœ¬"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "社群"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Renamed"
-msgstr "釿–°å‘½å..."
+msgid "Branches"
+msgstr "å»åˆï¼š"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Deleted"
-msgstr "刪除"
+msgid "Create New Branch"
+msgstr "新增"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Typechange"
-msgstr "當改變時更新"
+msgid "Remove Branch"
+msgstr "移除動畫軌跡"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage Selected"
-msgstr "刪除é¸ä¸­æª”案"
+msgid "Remotes"
+msgstr "移除"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Stage All"
-msgstr "å…¨é¸"
+msgid "Create New Remote"
+msgstr "新增"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
-msgid "Commit Changes"
-msgstr "åŒæ­¥æ›´æ–°è…³æœ¬"
+msgid "Remove Remote"
+msgstr "移除é¸é …"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "移除"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "移除"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
+msgid "Pull"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
+msgid "Push"
msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
+msgid "Force Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Modified"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Renamed"
+msgstr "釿–°å‘½å..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Deleted"
+msgstr "刪除"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Typechange"
+msgstr "當改變時更新"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unmerged"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "View:"
+msgstr "é è¦½:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Split"
+msgstr "編輯Node Curve"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Unified"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -12815,6 +12981,7 @@ msgid "Export list to a CSV file"
msgstr "匯出"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr ""
@@ -13704,6 +13871,39 @@ msgstr "釿–°æ•´ç†"
msgid "Edit Member"
msgstr "檔案"
+#: modules/visual_script/visual_script_expression.cpp
+msgid "Expression"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "新增動畫"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr ""
@@ -13716,6 +13916,82 @@ msgstr ""
msgid "Iterator became invalid: "
msgstr ""
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "釿–°å‘½å資料夾:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Switch"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Type Cast"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "有效字符:"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Mod %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftLeft %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitAnd %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr ""
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr ""
@@ -13732,6 +14008,19 @@ msgstr ""
msgid "Invalid index property name '%s' in node %s."
msgstr ""
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Emit %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "行為"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Compose Array"
+msgstr ""
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ""
@@ -13741,6 +14030,10 @@ msgid ": Invalid arguments: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr ""
@@ -13749,6 +14042,62 @@ msgid "VariableSet not found in script: "
msgstr ""
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "新增節點"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Index"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Engine Singleton"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "儲存場景"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "峿™‚編輯"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Self"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "貼上"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr ""
@@ -13758,15 +14107,74 @@ msgid ""
"(error)."
msgstr ""
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "SubCall"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Get Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Set Local Var"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "行為"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
#, fuzzy
msgid "Search VisualScript"
msgstr "貼上"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "移動模å¼"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "物ç†å¹€ %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
msgstr ""
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "訊號"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "訊號"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "Instance"
+
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
msgstr ""
@@ -14359,7 +14767,16 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
msgstr ""
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
@@ -14574,7 +14991,15 @@ msgstr ""
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
msgstr ""
#: scene/3d/particles.cpp
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index c75612316a..ba318ee632 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -383,6 +383,7 @@ msgstr "確定è¦å»ºç«‹ %d 個動畫軌並æ’入畫格嗎?"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/mesh_instance_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_create_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -843,6 +844,7 @@ msgstr "新增"
#: editor/groups_editor.cpp editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/plugins/resource_preloader_editor_plugin.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp
msgid "Remove"
@@ -892,8 +894,7 @@ msgstr "無法連接訊號"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#: editor/plugins/theme_editor_plugin.cpp
-#: editor/plugins/version_control_editor_plugin.cpp editor/project_export.cpp
+#: editor/plugins/theme_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/property_editor.cpp
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -1939,7 +1940,6 @@ msgid "New Folder..."
msgstr "新增資料夾..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
msgstr "釿–°æ•´ç†"
@@ -2056,7 +2056,8 @@ msgstr "資料夾與檔案:"
msgid "Preview:"
msgstr "é è¦½ï¼š"
-#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
+#: editor/editor_file_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp scene/gui/file_dialog.cpp
msgid "File:"
msgstr "檔案:"
@@ -2227,7 +2228,7 @@ msgstr "方法"
msgid "Signal"
msgstr "訊號"
-#: editor/editor_help_search.cpp
+#: editor/editor_help_search.cpp modules/visual_script/visual_script_nodes.cpp
msgid "Constant"
msgstr "常數"
@@ -2258,6 +2259,8 @@ msgid "Pin value [Disabled because '%s' is editor-only]"
msgstr ""
#: editor/editor_inspector.cpp editor/scene_tree_dock.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
msgstr "設定 %s"
@@ -2985,8 +2988,9 @@ msgid "Install Android Build Template..."
msgstr "å®‰è£ Android 建置樣æ¿..."
#: editor/editor_node.cpp
-msgid "Open Project Data Folder"
-msgstr "開啟專案資料目錄"
+#, fuzzy
+msgid "Open User Data Folder"
+msgstr "開啟編輯器資料目錄"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
@@ -3132,10 +3136,6 @@ msgid "Toggle Fullscreen"
msgstr "開啟ï¼å–消全螢幕顯示"
#: editor/editor_node.cpp
-msgid "Toggle System Console"
-msgstr "開啟ï¼é—œé–‰ç³»çµ±ä¸»æŽ§å°"
-
-#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
msgstr "開啟編輯器資料ï¼ç·¨è¼¯å™¨è¨­å®šè³‡æ–™å¤¾"
@@ -3362,6 +3362,7 @@ msgid "Load Errors"
msgstr "載入錯誤"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Select"
msgstr "鏿“‡"
@@ -3438,7 +3439,6 @@ msgid "Author"
msgstr "作者"
#: editor/editor_plugin_settings.cpp
-#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
msgstr "狀態"
@@ -3674,6 +3674,12 @@ msgstr "場景路徑:"
msgid "Import From Node:"
msgstr "自節點中匯入:"
+#. TRANSLATORS: %s refers to the name of a version control system (e.g. "Git").
+#: editor/editor_vcs_interface.cpp
+#, fuzzy
+msgid "%s Error"
+msgstr "錯誤"
+
#: editor/export_template_manager.cpp
msgid "Open the folder containing these templates."
msgstr "開啟包å«é€™äº›æ¨£æ¿çš„資料夾。"
@@ -4545,6 +4551,7 @@ msgid "Subfolder:"
msgstr "å­è³‡æ–™å¤¾ï¼š"
#: editor/plugin_config_dialog.cpp
+#: editor/plugins/version_control_editor_plugin.cpp
msgid "Author:"
msgstr "作者:"
@@ -6214,6 +6221,7 @@ msgid "Zoom to 1600%"
msgstr "縮放至1600%"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Add %s"
msgstr "新增 %"
@@ -9555,7 +9563,8 @@ msgid "TileSet"
msgstr "圖塊集"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No VCS addons are available."
+#, fuzzy
+msgid "No VCS plugins are available."
msgstr "ç„¡å¯ç”¨çš„版本控制 (VCS) 擴充功能。"
#: editor/plugins/version_control_editor_plugin.cpp
@@ -9563,16 +9572,56 @@ msgid "Error"
msgstr "錯誤"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No files added to stage"
-msgstr "é å­˜å€ç„¡æª”案"
+msgid ""
+"Remote settings are empty. VCS features that use the network may not work."
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "No commit message was provided."
+msgstr "未æä¾›å稱。"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Commit"
msgstr "æäº¤"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "VCS Addon is not initialized"
-msgstr "VCS 擴充功能尚未åˆå§‹åŒ–"
+#, fuzzy
+msgid "Staged Changes"
+msgstr "著色器變更:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "著色器變更:"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit:"
+msgstr "æäº¤"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Date:"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Subtitle:"
+msgstr "å­æ¨¹"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Do you want to remove the %s branch?"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Do you want to remove the %s remote?"
+msgstr "ç¢ºå®šè¦æ‰“開多個專案嗎?"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Apply"
+msgstr "套用é‡è¨­"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
@@ -9583,16 +9632,148 @@ msgid "Initialize"
msgstr "åˆå§‹åŒ–"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Staging area"
-msgstr "é å­˜å€"
+#, fuzzy
+msgid "Remote Login"
+msgstr "移除控制點"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Username"
+msgstr "釿–°å‘½å"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Password"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Public Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH public key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Private Key Path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Select SSH private key path"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "SSH Passphrase"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect new changes"
msgstr "嵿¸¬æ–°æ”¹å‹•"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Changes"
-msgstr "改動"
+#, fuzzy
+msgid "Discard all changes"
+msgstr "關閉並ä¿å­˜ä¿®æ”¹å—Žï¼Ÿ"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Stage all changes"
+msgstr "正在儲存變更..."
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Unstage all changes"
+msgstr "æè³ªè®Šæ›´ï¼š"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit Message"
+msgstr "æäº¤æ”¹å‹•"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit Changes"
+msgstr "æäº¤æ”¹å‹•"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Commit List"
+msgstr "æäº¤"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Commit list size"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "10"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "20"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "30"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Branches"
+msgstr "ç¬¦åˆæ¢ä»¶ï¼š"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Branch"
+msgstr "建立新專案"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Branch"
+msgstr "刪除動畫軌"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Branch Name"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remotes"
+msgstr "é ç«¯"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Create New Remote"
+msgstr "建立新專案"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remove Remote"
+msgstr "移除項目"
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote Name"
+msgstr "é ç«¯ "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Remote URL"
+msgstr "é ç«¯ "
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Fetch"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Pull"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+msgid "Push"
+msgstr ""
+
+#: editor/plugins/version_control_editor_plugin.cpp
+#, fuzzy
+msgid "Force Push"
+msgstr "來æºç¶²æ ¼ï¼š"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -9611,28 +9792,23 @@ msgid "Typechange"
msgstr "æ ¼å¼æ›´æ”¹"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage Selected"
-msgstr "é å­˜æ‰€é¸"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Stage All"
-msgstr "é å­˜å…¨éƒ¨"
-
-#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Commit Changes"
-msgstr "æäº¤æ”¹å‹•"
+msgid "Unmerged"
+msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "View file diffs before committing them to the latest version"
-msgstr "在æäº¤è‡³æœ€æ–°ç‰ˆæœ¬å‰æª¢è¦–檔案的差異"
+#, fuzzy
+msgid "View:"
+msgstr "檢視"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "No file diff is active"
-msgstr "無有效的檔案差異"
+#, fuzzy
+msgid "Split"
+msgstr "拆分路徑"
#: editor/plugins/version_control_editor_plugin.cpp
-msgid "Detect changes in file diff"
-msgstr "åœ¨æª”æ¡ˆå·®ç•°ä¸­åµæ¸¬æ”¹å‹•"
+#, fuzzy
+msgid "Unified"
+msgstr "已修改"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
@@ -12246,6 +12422,7 @@ msgid "Export list to a CSV file"
msgstr "匯出列表至 CSV 檔案"
#: editor/script_editor_debugger.cpp
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Resource Path"
msgstr "資æºè·¯å¾‘"
@@ -13077,6 +13254,40 @@ msgstr "釿–°æ•´ç†åœ–表"
msgid "Edit Member"
msgstr "編輯æˆå“¡"
+#: modules/visual_script/visual_script_expression.cpp
+#, fuzzy
+msgid "Expression"
+msgstr "設定表示å¼"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Return"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Condition"
+msgstr "å‹•ç•«"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "if (cond) is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "While"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "while (cond):"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Iterator"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "for (elem) in (input):"
+msgstr ""
+
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
msgstr "輸入型別éžå¯è¿­ä»£åž‹åˆ¥ï¼š "
@@ -13089,6 +13300,88 @@ msgstr "迭代器已ä¸å¯ç”¨"
msgid "Iterator became invalid: "
msgstr "迭代器已ä¸å¯ç”¨ï¼š "
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Sequence"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "in order:"
+msgstr "釿–°å‘½å資料夾:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Switch"
+msgstr "仰角:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "'input' is:"
+msgstr ""
+
+#: modules/visual_script/visual_script_flow_control.cpp
+#, fuzzy
+msgid "Type Cast"
+msgstr "類別:"
+
+#: modules/visual_script/visual_script_flow_control.cpp
+msgid "Is %s?"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "On %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "On Self"
+msgstr "僅自己"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Subtract %s"
+msgstr "使–¼å­—å…ƒ %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Multiply %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "Divide %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Mod %s"
+msgstr "新增 %"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "ShiftLeft %s"
+msgstr "設定 %s"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "ShiftRight %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "BitAnd %s"
+msgstr "新增 %"
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitOr %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+msgid "BitXor %s"
+msgstr ""
+
+#: modules/visual_script/visual_script_func_nodes.cpp
+#: modules/visual_script/visual_script_nodes.cpp
+#: modules/visual_script/visual_script_property_selector.cpp
+msgid "Get %s"
+msgstr "å–å¾— %s"
+
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
msgstr "無效的索引屬性å稱。"
@@ -13105,6 +13398,21 @@ msgstr "路徑未指å‘節點ï¼"
msgid "Invalid index property name '%s' in node %s."
msgstr "無效的索引屬性å稱「%sã€ï¼Œæ–¼ç¯€é»žã€Œ%sã€ã€‚"
+#: modules/visual_script/visual_script_func_nodes.cpp
+#, fuzzy
+msgid "Emit %s"
+msgstr "設定 %s"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Function"
+msgstr "函å¼"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Compose Array"
+msgstr "調整陣列大å°"
+
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
msgstr ": 無效的引數型別: "
@@ -13114,6 +13422,10 @@ msgid ": Invalid arguments: "
msgstr ": 無效的引數: "
#: modules/visual_script/visual_script_nodes.cpp
+msgid "a if cond, else b"
+msgstr ""
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
msgstr "腳本中未找到 VariableGet(å–得變數): "
@@ -13122,6 +13434,66 @@ msgid "VariableSet not found in script: "
msgstr "腳本中未找到 VariableSet(設定變數): "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Preload"
+msgstr "釿–°è¼‰å…¥"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Index"
+msgstr "Z 索引"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Index"
+msgstr "Z 索引"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Global Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Class Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Basic Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Math Constant"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Engine Singleton"
+msgstr "啟用 GDNative 單例"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Node"
+msgstr "TimeSeek 節點"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Scene Tree"
+msgstr "正在編輯場景樹"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Self"
+msgstr "僅自己"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "CustomNode"
+msgstr "剪下節點"
+
+#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
msgstr "自定節點沒有 _step() 方法,無法產生圖表。"
@@ -13131,13 +13503,75 @@ msgid ""
"(error)."
msgstr "_step() 的回傳值無效,必須為整數 (Seq Out) 或字串 (Error)。"
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "SubCall"
+msgstr "呼å«"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Construct %s"
+msgstr "常數"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Get Local Var"
+msgstr "使用本機空間"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Set Local Var"
+msgstr "使用本機空間"
+
+#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
+msgid "Action %s"
+msgstr "æ“作"
+
+#: modules/visual_script/visual_script_nodes.cpp
+msgid "Deconstruct %s"
+msgstr ""
+
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
msgstr "æœå°‹è¦–覺腳本 (VisualScript)"
-#: modules/visual_script/visual_script_property_selector.cpp
-msgid "Get %s"
-msgstr "å–å¾— %s"
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Yield"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "Wait"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Frame"
+msgstr "貼上影格"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "Next Physics Frame"
+msgstr "物ç†å½±æ ¼ %"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+msgid "%s sec(s)"
+msgstr ""
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitSignal"
+msgstr "訊號"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitNodeSignal"
+msgstr "訊號"
+
+#: modules/visual_script/visual_script_yield_nodes.cpp
+#, fuzzy
+msgid "WaitInstanceSignal"
+msgstr "實體"
#: platform/android/export/export_plugin.cpp
msgid "Package name is missing."
@@ -13734,14 +14168,24 @@ msgid ""
msgstr "ParallaxLayer 節點僅在當其被設為 ParallaxBackground çš„å­ç¯€é»žæ™‚有效。"
#: scene/2d/particles_2d.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles2D node instead. You can use the \"Convert to "
-"CPUParticles\" option for this purpose."
+"CPUParticles2D\" toolbar option for this purpose."
msgstr ""
"GLES2 視訊驅動程å¼ç›®å‰ä¸æ”¯æ´åŸºæ–¼ GPU 的粒å­ã€‚\n"
"請改為使用 CPUParticles2D 節點。å¯ä½¿ç”¨ã€ŒConvert to CPUParticlesã€é¸é …。"
+#: scene/2d/particles_2d.cpp
+msgid ""
+"On macOS, Particles2D rendering is much slower than CPUParticles2D due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles2D instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles2D\" toolbar option for this "
+"purpose."
+msgstr ""
+
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
"A material to process the particles is not assigned, so no behavior is "
@@ -13970,16 +14414,25 @@ msgid "Only uniform scales are supported."
msgstr "僅支æ´å‡ç­‰ç¸®æ”¾ã€‚"
#: scene/3d/particles.cpp
+#, fuzzy
msgid ""
"GPU-based particles are not supported by the GLES2 video driver.\n"
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
-"\" option for this purpose."
+"\" toolbar option for this purpose."
msgstr ""
"GLES2 視訊驅動程å¼ä¸æ”¯æ´åŸºæ–¼ GPU 的粒å­ã€‚\n"
"請改為使用 CPUParticles 節點。å¯ä½¿ç”¨ã€ŒConvert to CPUParticlesã€é¸é …。"
#: scene/3d/particles.cpp
msgid ""
+"On macOS, Particles rendering is much slower than CPUParticles due to "
+"transform feedback being implemented on the CPU instead of the GPU.\n"
+"Consider using CPUParticles instead when targeting macOS.\n"
+"You can use the \"Convert to CPUParticles\" toolbar option for this purpose."
+msgstr ""
+
+#: scene/3d/particles.cpp
+msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr "由於網格尚未被指派至æç¹ªè·¯å¾‘(Draw Pass),未顯示任何æ±è¥¿ã€‚"
diff --git a/gles3_builders.py b/gles3_builders.py
index 5288e66cc2..4f9247c938 100644
--- a/gles3_builders.py
+++ b/gles3_builders.py
@@ -6,16 +6,12 @@ All such functions are invoked in a subprocess on Windows to prevent build flaki
from platform_methods import subprocess_main
-class LegacyGLHeaderStruct:
+class GLES3HeaderStruct:
def __init__(self):
self.vertex_lines = []
self.fragment_lines = []
self.uniforms = []
- self.attributes = []
- self.feedbacks = []
self.fbos = []
- self.conditionals = []
- self.enums = {}
self.texunits = []
self.texunit_names = []
self.ubos = []
@@ -28,22 +24,64 @@ class LegacyGLHeaderStruct:
self.line_offset = 0
self.vertex_offset = 0
self.fragment_offset = 0
+ self.variant_defines = []
+ self.variant_names = []
+ self.specialization_names = []
+ self.specialization_values = []
-def include_file_in_legacygl_header(filename, header_data, depth):
+def include_file_in_gles3_header(filename, header_data, depth):
fs = open(filename, "r")
line = fs.readline()
while line:
- if line.find("[vertex]") != -1:
+ if line.find("=") != -1 and header_data.reading == "":
+ # Mode
+ eqpos = line.find("=")
+ defname = line[:eqpos].strip().upper()
+ define = line[eqpos + 1 :].strip()
+ header_data.variant_names.append(defname)
+ header_data.variant_defines.append(define)
+ line = fs.readline()
+ header_data.line_offset += 1
+ header_data.vertex_offset = header_data.line_offset
+ continue
+
+ if line.find("=") != -1 and header_data.reading == "specializations":
+ # Specialization
+ eqpos = line.find("=")
+ specname = line[:eqpos].strip()
+ specvalue = line[eqpos + 1 :]
+ header_data.specialization_names.append(specname)
+ header_data.specialization_values.append(specvalue)
+ line = fs.readline()
+ header_data.line_offset += 1
+ header_data.vertex_offset = header_data.line_offset
+ continue
+
+ if line.find("#[modes]") != -1:
+ # Nothing really, just skip
+ line = fs.readline()
+ header_data.line_offset += 1
+ header_data.vertex_offset = header_data.line_offset
+ continue
+
+ if line.find("#[specializations]") != -1:
+ header_data.reading = "specializations"
+ line = fs.readline()
+ header_data.line_offset += 1
+ header_data.vertex_offset = header_data.line_offset
+ continue
+
+ if line.find("#[vertex]") != -1:
header_data.reading = "vertex"
line = fs.readline()
header_data.line_offset += 1
header_data.vertex_offset = header_data.line_offset
continue
- if line.find("[fragment]") != -1:
+ if line.find("#[fragment]") != -1:
header_data.reading = "fragment"
line = fs.readline()
header_data.line_offset += 1
@@ -58,31 +96,15 @@ def include_file_in_legacygl_header(filename, header_data, depth):
included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
header_data.vertex_included_files += [included_file]
- if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
+ if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
header_data.fragment_included_files += [included_file]
- if include_file_in_legacygl_header(included_file, header_data, depth + 1) is None:
+ if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
line = fs.readline()
- if line.find("#ifdef ") != -1:
- if line.find("#ifdef ") != -1:
- ifdefline = line.replace("#ifdef ", "").strip()
-
- if line.find("_EN_") != -1:
- enumbase = ifdefline[: ifdefline.find("_EN_")]
- ifdefline = ifdefline.replace("_EN_", "_")
- line = line.replace("_EN_", "_")
- if enumbase not in header_data.enums:
- header_data.enums[enumbase] = []
- if ifdefline not in header_data.enums[enumbase]:
- header_data.enums[enumbase].append(ifdefline)
-
- elif not ifdefline in header_data.conditionals:
- header_data.conditionals += [ifdefline]
-
if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
# texture unit
texunitstr = line[line.find(":") + 1 :].strip()
@@ -144,33 +166,6 @@ def include_file_in_legacygl_header(filename, header_data, depth):
if not x in header_data.uniforms:
header_data.uniforms += [x]
- if line.strip().find("attribute ") == 0 and line.find("attrib:") != -1:
- uline = line.replace("in ", "")
- uline = uline.replace("attribute ", "")
- uline = uline.replace("highp ", "")
- uline = uline.replace(";", "")
- uline = uline[uline.find(" ") :].strip()
-
- if uline.find("//") != -1:
- name, bind = uline.split("//")
- if bind.find("attrib:") != -1:
- name = name.strip()
- bind = bind.replace("attrib:", "").strip()
- header_data.attributes += [(name, bind)]
-
- if line.strip().find("out ") == 0 and line.find("tfb:") != -1:
- uline = line.replace("out ", "")
- uline = uline.replace("highp ", "")
- uline = uline.replace(";", "")
- uline = uline[uline.find(" ") :].strip()
-
- if uline.find("//") != -1:
- name, bind = uline.split("//")
- if bind.find("tfb:") != -1:
- name = name.strip()
- bind = bind.replace("tfb:", "").strip()
- header_data.feedbacks += [(name, bind)]
-
line = line.replace("\r", "")
line = line.replace("\n", "")
@@ -187,12 +182,14 @@ def include_file_in_legacygl_header(filename, header_data, depth):
return header_data
-def build_legacygl_header(filename, include, class_suffix, output_attribs):
- header_data = LegacyGLHeaderStruct()
- include_file_in_legacygl_header(filename, header_data, 0)
+def build_gles3_header(filename, include, class_suffix, output_attribs):
+ header_data = GLES3HeaderStruct()
+ include_file_in_gles3_header(filename, header_data, 0)
out_file = filename + ".gen.h"
fd = open(out_file, "w")
+ defspec = 0
+ defvariant = ""
enum_constants = []
@@ -202,8 +199,8 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
out_file_ifdef = out_file_base.replace(".", "_").upper()
- fd.write("#ifndef " + out_file_ifdef + class_suffix + "_120\n")
- fd.write("#define " + out_file_ifdef + class_suffix + "_120\n")
+ fd.write("#ifndef " + out_file_ifdef + class_suffix + "_GLES3\n")
+ fd.write("#define " + out_file_ifdef + class_suffix + "_GLES3\n")
out_file_class = (
out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
@@ -211,117 +208,206 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write("\n\n")
fd.write('#include "' + include + '"\n\n\n')
fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n")
- fd.write('\t virtual String get_shader_name() const { return "' + out_file_class + '"; }\n')
fd.write("public:\n\n")
- if header_data.conditionals:
- fd.write("\tenum Conditionals {\n")
- for x in header_data.conditionals:
- fd.write("\t\t" + x.upper() + ",\n")
- fd.write("\t};\n\n")
-
if header_data.uniforms:
fd.write("\tenum Uniforms {\n")
for x in header_data.uniforms:
fd.write("\t\t" + x.upper() + ",\n")
fd.write("\t};\n\n")
- fd.write("\t_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }\n\n")
- if header_data.conditionals:
- fd.write(
- "\t_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }\n\n"
- )
- fd.write("\t#ifdef DEBUG_ENABLED\n ")
- fd.write(
- "\t#define _FU if (get_uniform(p_uniform)<0) return; if (!is_version_valid()) return; ERR_FAIL_COND( get_active()!=this ); \n\n "
- )
- fd.write("\t#else\n ")
- fd.write("\t#define _FU if (get_uniform(p_uniform)<0) return; \n\n ")
- fd.write("\t#endif\n")
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={(GLfloat)p_vec2.x,(GLfloat)p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Size2i& p_vec2) { _FU GLint vec2[2]={(GLint)p_vec2.x,(GLint)p_vec2.y}; glUniform2iv(get_uniform(p_uniform),1,vec2); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={(GLfloat)p_vec3.x,(GLfloat)p_vec3.y,(GLfloat)p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }\n\n"
- )
- fd.write(
- "\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }\n\n"
- )
-
- fd.write(
- """\t_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform3D& p_transform) { _FU
+ if header_data.variant_names:
+ fd.write("\tenum ShaderVariant {\n")
+ for x in header_data.variant_names:
+ fd.write("\t\t" + x + ",\n")
+ fd.write("\t};\n\n")
+ else:
+ fd.write("\tenum ShaderVariant { DEFAULT };\n\n")
+ defvariant = "=DEFAULT"
+
+ if header_data.specialization_names:
+ fd.write("\tenum Specializations {\n")
+ counter = 0
+ for x in header_data.specialization_names:
+ fd.write("\t\t" + x.upper() + "=" + str(1 << counter) + ",\n")
+ counter += 1
+ fd.write("\t};\n\n")
- const Transform3D &tr = p_transform;
+ for i in range(len(header_data.specialization_names)):
+ defval = header_data.specialization_values[i].strip()
+ if defval.upper() == "TRUE" or defval == "1":
+ defspec |= 1 << i
- GLfloat matrix[16]={ /* build a 16x16 matrix */
- (GLfloat)tr.basis.elements[0][0],
- (GLfloat)tr.basis.elements[1][0],
- (GLfloat)tr.basis.elements[2][0],
- (GLfloat)0,
- (GLfloat)tr.basis.elements[0][1],
- (GLfloat)tr.basis.elements[1][1],
- (GLfloat)tr.basis.elements[2][1],
- (GLfloat)0,
- (GLfloat)tr.basis.elements[0][2],
- (GLfloat)tr.basis.elements[1][2],
- (GLfloat)tr.basis.elements[2][2],
- (GLfloat)0,
- (GLfloat)tr.origin.x,
- (GLfloat)tr.origin.y,
- (GLfloat)tr.origin.z,
- (GLfloat)1
- };
+ fd.write(
+ "\t_FORCE_INLINE_ void version_bind_shader(RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _version_bind_shader(p_version,p_variant,p_specialization); }\n\n"
+ )
+ if header_data.uniforms:
+ fd.write(
+ "\t_FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { return _version_get_uniform(p_uniform,p_version,p_variant,p_specialization); }\n\n"
+ )
- glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
+ fd.write(
+ "\t#define _FU if (version_get_uniform(p_uniform,p_version,p_variant,p_specialization)<0) return; \n\n "
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color& p_color,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,col); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2& p_vec2,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU GLfloat vec2[2]={float(p_vec2.x),float(p_vec2.y)}; glUniform2fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i& p_vec2,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU GLint vec2[2]={GLint(p_vec2.x),GLint(p_vec2.y)}; glUniform2iv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3& p_vec3,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU GLfloat vec3[3]={float(p_vec3.x),float(p_vec3.y),float(p_vec3.z)}; glUniform3fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec3); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform2f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform3f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c); }\n\n"
+ )
+ fd.write(
+ "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d,RID p_version,ShaderVariant p_variant"
+ + defvariant
+ + ",uint64_t p_specialization="
+ + str(defspec)
+ + ") { _FU glUniform4f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c,p_d); }\n\n"
+ )
+ fd.write(
+ """\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D& p_transform,RID p_version,ShaderVariant p_variant"""
+ + defvariant
+ + """,uint64_t p_specialization="""
+ + str(defspec)
+ + """) { _FU
+
+ const Transform3D &tr = p_transform;
+
+ GLfloat matrix[16]={ /* build a 16x16 matrix */
+ (GLfloat)tr.basis.elements[0][0],
+ (GLfloat)tr.basis.elements[1][0],
+ (GLfloat)tr.basis.elements[2][0],
+ (GLfloat)0,
+ (GLfloat)tr.basis.elements[0][1],
+ (GLfloat)tr.basis.elements[1][1],
+ (GLfloat)tr.basis.elements[2][1],
+ (GLfloat)0,
+ (GLfloat)tr.basis.elements[0][2],
+ (GLfloat)tr.basis.elements[1][2],
+ (GLfloat)tr.basis.elements[2][2],
+ (GLfloat)0,
+ (GLfloat)tr.origin.x,
+ (GLfloat)tr.origin.y,
+ (GLfloat)tr.origin.z,
+ (GLfloat)1
+ };
+
+ glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
- }
+ }
- """
- )
+ """
+ )
- fd.write(
- """_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform2D& p_transform) { _FU
+ fd.write(
+ """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D& p_transform,RID p_version,ShaderVariant p_variant"""
+ + defvariant
+ + """,uint64_t p_specialization="""
+ + str(defspec)
+ + """) { _FU
- const Transform2D &tr = p_transform;
+ const Transform2D &tr = p_transform;
GLfloat matrix[16]={ /* build a 16x16 matrix */
(GLfloat)tr.elements[0][0],
@@ -342,90 +428,37 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
(GLfloat)1
};
+ glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
- glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
-
-
- }
-
- """
- )
-
- fd.write(
- """_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU
-
- GLfloat matrix[16];
-
- for (int i=0;i<4;i++) {
- for (int j=0;j<4;j++) {
- matrix[i*4+j]=p_matrix.matrix[i][j];
- }
}
- glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
-}"""
- )
-
- fd.write("\n\n#undef _FU\n\n\n")
-
- fd.write("\tvirtual void init() {\n\n")
-
- enum_value_count = 0
-
- if header_data.enums:
-
- fd.write("\t\t//Written using math, given nonstandarity of 64 bits integer constants..\n")
- fd.write("\t\tstatic const Enum _enums[]={\n")
-
- bitofs = len(header_data.conditionals)
- enum_vals = []
-
- for xv in header_data.enums:
- x = header_data.enums[xv]
- bits = 1
- amt = len(x)
- while 2 ** bits < amt:
- bits += 1
- strs = "{"
- for i in range(amt):
- strs += '"#define ' + x[i] + '\\n",'
-
- c = {}
- c["set_mask"] = "uint64_t(" + str(i) + ")<<" + str(bitofs)
- c["clear_mask"] = (
- "((uint64_t(1)<<40)-1) ^ (((uint64_t(1)<<" + str(bits) + ") - 1)<<" + str(bitofs) + ")"
- )
- enum_vals.append(c)
- enum_constants.append(x[i])
-
- strs += "NULL}"
-
- fd.write(
- "\t\t\t{(uint64_t(1<<" + str(bits) + ")-1)<<" + str(bitofs) + "," + str(bitofs) + "," + strs + "},\n"
- )
- bitofs += bits
-
- fd.write("\t\t};\n\n")
+ """
+ )
- fd.write("\t\tstatic const EnumValue _enum_values[]={\n")
+ fd.write(
+ """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant"""
+ + defvariant
+ + """,uint64_t p_specialization="""
+ + str(defspec)
+ + """) { _FU
+
+ GLfloat matrix[16];
+
+ for (int i=0;i<4;i++) {
+ for (int j=0;j<4;j++) {
+ matrix[i*4+j]=p_matrix.matrix[i][j];
+ }
+ }
- enum_value_count = len(enum_vals)
- for x in enum_vals:
- fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n")
+ glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
+ }"""
+ )
- fd.write("\t\t};\n\n")
+ fd.write("\n\n#undef _FU\n\n\n")
- conditionals_found = []
- if header_data.conditionals:
+ fd.write("protected:\n\n")
- fd.write("\t\tstatic const char* _conditional_strings[]={\n")
- if header_data.conditionals:
- for x in header_data.conditionals:
- fd.write('\t\t\t"#define ' + x + '\\n",\n')
- conditionals_found.append(x)
- fd.write("\t\t};\n\n")
- else:
- fd.write("\t\tstatic const char **_conditional_strings=NULL;\n")
+ fd.write("\tvirtual void _init() override {\n\n")
if header_data.uniforms:
@@ -435,19 +468,18 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write('\t\t\t"' + x + '",\n')
fd.write("\t\t};\n\n")
else:
- fd.write("\t\tstatic const char **_uniform_strings=NULL;\n")
-
- if output_attribs:
- if header_data.attributes:
+ fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n")
- fd.write("\t\tstatic AttributePair _attribute_pairs[]={\n")
- for x in header_data.attributes:
- fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
- fd.write("\t\t};\n\n")
- else:
- fd.write("\t\tstatic AttributePair *_attribute_pairs=NULL;\n")
+ variant_count = 1
+ if len(header_data.variant_defines) > 0:
- feedback_count = 0
+ fd.write("\t\tstatic const char* _variant_defines[]={\n")
+ for x in header_data.variant_defines:
+ fd.write('\t\t\t"' + x + '",\n')
+ fd.write("\t\t};\n\n")
+ variant_count = len(header_data.variant_defines)
+ else:
+ fd.write("\t\tstatic const char **_variant_defines[]={" "};\n")
if header_data.texunits:
fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
@@ -455,7 +487,29 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
fd.write("\t\t};\n\n")
else:
- fd.write("\t\tstatic TexUnitPair *_texunit_pairs=NULL;\n")
+ fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n")
+
+ if header_data.ubos:
+ fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n")
+ for x in header_data.ubos:
+ fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
+ fd.write("\t\t};\n\n")
+ else:
+ fd.write("\t\tstatic UBOPair *_ubo_pairs=nullptr;\n")
+
+ if header_data.specialization_names:
+ fd.write("\t\tstatic Specialization _spec_pairs[]={\n")
+ for i in range(len(header_data.specialization_names)):
+ defval = header_data.specialization_values[i].strip()
+ if defval.upper() == "TRUE" or defval == "1":
+ defal = "true"
+ else:
+ defval = "false"
+
+ fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n")
+ fd.write("\t\t};\n\n")
+ else:
+ fd.write("\t\tstatic Specialization *_spec_pairs=nullptr;\n")
fd.write("\t\tstatic const char _vertex_code[]={\n")
for x in header_data.vertex_lines:
@@ -465,8 +519,6 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write(str(ord("\n")) + ",")
fd.write("\t\t0};\n\n")
- fd.write("\t\tstatic const int _vertex_code_start=" + str(header_data.vertex_offset) + ";\n")
-
fd.write("\t\tstatic const char _fragment_code[]={\n")
for x in header_data.fragment_lines:
for c in x:
@@ -475,45 +527,24 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
fd.write(str(ord("\n")) + ",")
fd.write("\t\t0};\n\n")
- fd.write("\t\tstatic const int _fragment_code_start=" + str(header_data.fragment_offset) + ";\n")
-
- if output_attribs:
- fd.write(
- "\t\tsetup(_conditional_strings,"
- + str(len(header_data.conditionals))
- + ",_uniform_strings,"
- + str(len(header_data.uniforms))
- + ",_attribute_pairs,"
- + str(len(header_data.attributes))
- + ", _texunit_pairs,"
- + str(len(header_data.texunits))
- + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
- )
- else:
- fd.write(
- "\t\tsetup(_conditional_strings,"
- + str(len(header_data.conditionals))
- + ",_uniform_strings,"
- + str(len(header_data.uniforms))
- + ",_texunit_pairs,"
- + str(len(header_data.texunits))
- + ",_enums,"
- + str(len(header_data.enums))
- + ",_enum_values,"
- + str(enum_value_count)
- + ",_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);\n"
- )
+ fd.write(
+ '\t\t_setup(_vertex_code,_fragment_code,"'
+ + out_file_class
+ + '",'
+ + str(len(header_data.uniforms))
+ + ",_uniform_strings,"
+ + str(len(header_data.ubos))
+ + ",_ubo_pairs,"
+ + str(len(header_data.texunits))
+ + ",_texunit_pairs,"
+ + str(len(header_data.specialization_names))
+ + ",_spec_pairs,"
+ + str(variant_count)
+ + ",_variant_defines);\n"
+ )
fd.write("\t}\n\n")
- if enum_constants:
-
- fd.write("\tenum EnumConditionals {\n")
- for x in enum_constants:
- fd.write("\t\t" + x.upper() + ",\n")
- fd.write("\t};\n\n")
- fd.write("\tvoid set_enum_conditional(EnumConditionals p_cond) { _set_enum_conditional(p_cond); }\n")
-
fd.write("};\n\n")
fd.write("#endif\n\n")
fd.close()
@@ -521,7 +552,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs):
def build_gles3_headers(target, source, env):
for x in source:
- build_legacygl_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True)
+ build_gles3_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True)
if __name__ == "__main__":
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index d17e880fc0..f816691cde 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -39,10 +39,6 @@
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <btBulletCollisionCommon.h>
-/**
- @author AndreaCatania
-*/
-
AreaBullet::AreaBullet() :
RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA) {
btGhost = bulletnew(btGhostObject);
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index caf81ef1be..740378d0e3 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -28,18 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef AREABULLET_H
-#define AREABULLET_H
+#ifndef AREA_BULLET_H
+#define AREA_BULLET_H
#include "collision_object_bullet.h"
#include "core/templates/vector.h"
#include "servers/physics_server_3d.h"
#include "space_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class btGhostObject;
class AreaBullet : public RigidCollisionObjectBullet {
@@ -163,4 +159,4 @@ public:
virtual void on_exit_area(AreaBullet *p_area);
};
-#endif
+#endif // AREA_BULLET_H
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index e67c9baacd..14bc7442a7 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -34,10 +34,6 @@
#include <LinearMath/btAabbUtil2.h>
-/**
- @author AndreaCatania
-*/
-
btRayShape::btRayShape(btScalar length) :
btConvexInternalShape() {
m_shapeType = CUSTOM_CONVEX_SHAPE_TYPE;
diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h
index 5d0a05b369..90e4524d64 100644
--- a/modules/bullet/btRayShape.h
+++ b/modules/bullet/btRayShape.h
@@ -35,10 +35,6 @@
#include <BulletCollision/CollisionShapes/btConvexInternalShape.h>
-/**
- @author AndreaCatania
-*/
-
/// Ray shape around z axis
ATTRIBUTE_ALIGNED16(class)
btRayShape : public btConvexInternalShape {
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 9bf3e186ee..7e9e621032 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -45,10 +45,6 @@
#include <assert.h>
-/**
- @author AndreaCatania
-*/
-
#define CreateThenReturnRID(owner, ridData) \
RID rid = owner.make_rid(ridData); \
ridData->set_self(rid); \
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index 5840eff815..06a6f62bcd 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -41,10 +41,6 @@
#include "soft_body_bullet.h"
#include "space_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class BulletPhysicsServer3D : public PhysicsServer3D {
GDCLASS(BulletPhysicsServer3D, PhysicsServer3D);
@@ -395,4 +391,4 @@ public:
JointBullet *get_joint(RID p_rid) const;
};
-#endif
+#endif // BULLET_PHYSICS_SERVER_H
diff --git a/modules/bullet/bullet_types_converter.cpp b/modules/bullet/bullet_types_converter.cpp
index 571457f48f..a0698683e8 100644
--- a/modules/bullet/bullet_types_converter.cpp
+++ b/modules/bullet/bullet_types_converter.cpp
@@ -30,10 +30,6 @@
#include "bullet_types_converter.h"
-/**
- @author AndreaCatania
-*/
-
// ++ BULLET to GODOT ++++++++++
void B_TO_G(btVector3 const &inVal, Vector3 &outVal) {
outVal[0] = inVal[0];
diff --git a/modules/bullet/bullet_types_converter.h b/modules/bullet/bullet_types_converter.h
index b4d6dccc05..4ee855c266 100644
--- a/modules/bullet/bullet_types_converter.h
+++ b/modules/bullet/bullet_types_converter.h
@@ -40,10 +40,6 @@
#include <LinearMath/btTransform.h>
#include <LinearMath/btVector3.h>
-/**
- @author AndreaCatania
-*/
-
// Bullet to Godot
extern void B_TO_G(btVector3 const &inVal, Vector3 &outVal);
extern void INVERT_B_TO_G(btVector3 const &inVal, Vector3 &outVal);
@@ -59,4 +55,5 @@ extern void INVERT_G_TO_B(Basis const &inVal, btMatrix3x3 &outVal);
extern void G_TO_B(Transform3D const &inVal, btTransform &outVal);
extern void UNSCALE_BT_BASIS(btTransform &scaledBasis);
-#endif
+
+#endif // BULLET_TYPES_CONVERTER_H
diff --git a/modules/bullet/bullet_utilities.h b/modules/bullet/bullet_utilities.h
index b832d3fc61..ab24cb5de6 100644
--- a/modules/bullet/bullet_utilities.h
+++ b/modules/bullet/bullet_utilities.h
@@ -31,10 +31,6 @@
#ifndef BULLET_UTILITIES_H
#define BULLET_UTILITIES_H
-/**
- @author AndreaCatania
-*/
-
#define bulletnew(cl) \
new cl
@@ -43,4 +39,5 @@
delete cl; \
cl = nullptr; \
}
-#endif
+
+#endif // BULLET_UTILITIES_H
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 6bf01a63df..bc8e1a0718 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -39,10 +39,6 @@
#include <btBulletCollisionCommon.h>
-/**
- @author AndreaCatania
-*/
-
// We enable dynamic AABB tree so that we can actually perform a broadphase on bodies with compound collision shapes.
// This is crucial for the performance of kinematic bodies and for bodies with transforming shapes.
#define enableDynamicAabbTree true
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 09be2d99d2..8e9c34df27 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -39,10 +39,6 @@
#include <LinearMath/btTransform.h>
-/**
- @author AndreaCatania
-*/
-
class AreaBullet;
class ShapeBullet;
class btCollisionObject;
@@ -256,4 +252,4 @@ private:
void internal_shape_destroy(int p_index, bool p_permanentlyFromThisBody = false);
};
-#endif
+#endif // COLLISION_OBJECT_BULLET_H
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index 544d711259..fc73036713 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -36,10 +36,6 @@
#include <BulletDynamics/ConstraintSolver/btConeTwistConstraint.h>
-/**
- @author AndreaCatania
-*/
-
ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) :
JointBullet() {
Transform3D scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale()));
diff --git a/modules/bullet/cone_twist_joint_bullet.h b/modules/bullet/cone_twist_joint_bullet.h
index ebb51868f4..c81e11f144 100644
--- a/modules/bullet/cone_twist_joint_bullet.h
+++ b/modules/bullet/cone_twist_joint_bullet.h
@@ -33,10 +33,6 @@
#include "joint_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class ConeTwistJointBullet : public JointBullet {
@@ -50,4 +46,5 @@ public:
void set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value);
real_t get_param(PhysicsServer3D::ConeTwistJointParam p_param) const;
};
-#endif
+
+#endif // CONE_TWIST_JOINT_BULLET_H
diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp
index 5b4b0e75bc..c788f09cb9 100644
--- a/modules/bullet/constraint_bullet.cpp
+++ b/modules/bullet/constraint_bullet.cpp
@@ -33,10 +33,6 @@
#include "collision_object_bullet.h"
#include "space_bullet.h"
-/**
- @author AndreaCatania
-*/
-
ConstraintBullet::ConstraintBullet() {}
void ConstraintBullet::setup(btTypedConstraint *p_constraint) {
diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h
index 5e63d7a1b5..5dc3958ee1 100644
--- a/modules/bullet/constraint_bullet.h
+++ b/modules/bullet/constraint_bullet.h
@@ -36,10 +36,6 @@
#include <BulletDynamics/ConstraintSolver/btTypedConstraint.h>
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class SpaceBullet;
class btTypedConstraint;
@@ -68,4 +64,5 @@ public:
_FORCE_INLINE_ btTypedConstraint *get_bt_constraint() { return constraint; }
};
-#endif
+
+#endif // CONSTRAINT_BULLET_H
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 01e1ecbdf6..0210064dc8 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -36,10 +36,6 @@
#include <BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h>
-/**
- @author AndreaCatania
-*/
-
Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
JointBullet() {
for (int i = 0; i < 3; i++) {
diff --git a/modules/bullet/generic_6dof_joint_bullet.h b/modules/bullet/generic_6dof_joint_bullet.h
index b5d1db8fd6..cc4ccf7ac4 100644
--- a/modules/bullet/generic_6dof_joint_bullet.h
+++ b/modules/bullet/generic_6dof_joint_bullet.h
@@ -33,10 +33,6 @@
#include "joint_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class Generic6DOFJointBullet : public JointBullet {
@@ -70,4 +66,4 @@ public:
bool get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const;
};
-#endif
+#endif // GENERIC_6DOF_JOINT_BULLET_H
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
index 0e872fa1c1..354c4e271b 100644
--- a/modules/bullet/godot_collision_configuration.cpp
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -35,10 +35,6 @@
#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
-/**
- @author AndreaCatania
-*/
-
GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
btDefaultCollisionConfiguration(constructionInfo) {
void *mem = nullptr;
diff --git a/modules/bullet/godot_collision_configuration.h b/modules/bullet/godot_collision_configuration.h
index 3b1bc3a97d..7e29f6e03a 100644
--- a/modules/bullet/godot_collision_configuration.h
+++ b/modules/bullet/godot_collision_configuration.h
@@ -34,10 +34,6 @@
#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
#include <BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h>
-/**
- @author AndreaCatania
-*/
-
class btDiscreteDynamicsWorld;
class GodotCollisionConfiguration : public btDefaultCollisionConfiguration {
@@ -63,4 +59,5 @@ public:
virtual btCollisionAlgorithmCreateFunc *getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1);
virtual btCollisionAlgorithmCreateFunc *getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1);
};
-#endif
+
+#endif // GODOT_COLLISION_CONFIGURATION_H
diff --git a/modules/bullet/godot_collision_dispatcher.cpp b/modules/bullet/godot_collision_dispatcher.cpp
index c926462eda..2ab1c7dd84 100644
--- a/modules/bullet/godot_collision_dispatcher.cpp
+++ b/modules/bullet/godot_collision_dispatcher.cpp
@@ -32,10 +32,6 @@
#include "collision_object_bullet.h"
-/**
- @author AndreaCatania
-*/
-
const int GodotCollisionDispatcher::CASTED_TYPE_AREA = static_cast<int>(CollisionObjectBullet::TYPE_AREA);
GodotCollisionDispatcher::GodotCollisionDispatcher(btCollisionConfiguration *collisionConfiguration) :
diff --git a/modules/bullet/godot_collision_dispatcher.h b/modules/bullet/godot_collision_dispatcher.h
index 77b8cee0a6..97cae1ce6a 100644
--- a/modules/bullet/godot_collision_dispatcher.h
+++ b/modules/bullet/godot_collision_dispatcher.h
@@ -31,14 +31,8 @@
#ifndef GODOT_COLLISION_DISPATCHER_H
#define GODOT_COLLISION_DISPATCHER_H
-#include <cstdint>
-
#include <btBulletDynamicsCommon.h>
-/**
- @author AndreaCatania
-*/
-
/// This class is required to implement custom collision behaviour in the narrowphase
class GodotCollisionDispatcher : public btCollisionDispatcher {
private:
@@ -49,4 +43,5 @@ public:
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1);
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1);
};
-#endif
+
+#endif // GODOT_COLLISION_DISPATCHER_H
diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h
index a37fef9d90..f1a5e0e3b5 100644
--- a/modules/bullet/godot_motion_state.h
+++ b/modules/bullet/godot_motion_state.h
@@ -35,10 +35,6 @@
#include <LinearMath/btMotionState.h>
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
// This class is responsible to move kinematic actor
@@ -96,4 +92,5 @@ public:
return bodyCurrentWorldTransform;
}
};
-#endif
+
+#endif // GODOT_MOTION_STATE_H
diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp
index 3b7513916d..697ca12e7b 100644
--- a/modules/bullet/godot_ray_world_algorithm.cpp
+++ b/modules/bullet/godot_ray_world_algorithm.cpp
@@ -35,10 +35,6 @@
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
-/**
- @author AndreaCatania
-*/
-
// Epsilon to account for floating point inaccuracies
#define RAY_PENETRATION_DEPTH_EPSILON 0.01
diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h
index f554108a75..94bdefb720 100644
--- a/modules/bullet/godot_ray_world_algorithm.h
+++ b/modules/bullet/godot_ray_world_algorithm.h
@@ -35,10 +35,6 @@
#include <BulletCollision/CollisionDispatch/btCollisionCreateFunc.h>
#include <BulletCollision/CollisionDispatch/btCollisionDispatcher.h>
-/**
- @author AndreaCatania
-*/
-
class btDiscreteDynamicsWorld;
class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm {
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index d4b6e90117..35b26fc2ec 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -34,11 +34,8 @@
#include "bullet_types_converter.h"
#include "collision_object_bullet.h"
#include "rigid_body_bullet.h"
-#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
-/**
- @author AndreaCatania
-*/
+#include <BulletCollision/CollisionDispatch/btInternalEdgeUtility.h>
bool godotContactAddedCallback(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
if (!colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound()) {
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 94be993212..dd64762529 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -36,10 +36,6 @@
#include <BulletCollision/BroadphaseCollision/btBroadphaseProxy.h>
#include <btBulletDynamicsCommon.h>
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
/// This callback is injected inside bullet server and allow me to smooth contacts against trimesh
@@ -225,4 +221,5 @@ struct GodotDeepPenetrationContactResultCallback : public btManifoldResult {
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth);
};
+
#endif // GODOT_RESULT_CALLBACKS_H
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 116d8caba7..0b1bb7890d 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -36,10 +36,6 @@
#include <BulletDynamics/ConstraintSolver/btHingeConstraint.h>
-/**
- @author AndreaCatania
-*/
-
HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameA, const Transform3D &frameB) :
JointBullet() {
Transform3D scaled_AFrame(frameA.scaled(rbA->get_body_scale()));
diff --git a/modules/bullet/hinge_joint_bullet.h b/modules/bullet/hinge_joint_bullet.h
index 7b87576442..5575be564f 100644
--- a/modules/bullet/hinge_joint_bullet.h
+++ b/modules/bullet/hinge_joint_bullet.h
@@ -33,10 +33,6 @@
#include "joint_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class HingeJointBullet : public JointBullet {
class btHingeConstraint *hingeConstraint;
@@ -54,4 +50,5 @@ public:
void set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value);
bool get_flag(PhysicsServer3D::HingeJointFlag p_flag) const;
};
-#endif
+
+#endif // HINGE_JOINT_BULLET_H
diff --git a/modules/bullet/joint_bullet.cpp b/modules/bullet/joint_bullet.cpp
deleted file mode 100644
index 65a891e890..0000000000
--- a/modules/bullet/joint_bullet.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*************************************************************************/
-/* joint_bullet.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 "joint_bullet.h"
-
-#include "space_bullet.h"
-
-/**
- @author AndreaCatania
-*/
-
-JointBullet::JointBullet() :
- ConstraintBullet() {}
-
-JointBullet::~JointBullet() {}
diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h
index 75f6055b2f..427221dd77 100644
--- a/modules/bullet/joint_bullet.h
+++ b/modules/bullet/joint_bullet.h
@@ -34,18 +34,15 @@
#include "constraint_bullet.h"
#include "servers/physics_server_3d.h"
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class btTypedConstraint;
class JointBullet : public ConstraintBullet {
public:
- JointBullet();
- virtual ~JointBullet();
+ JointBullet() {}
+ virtual ~JointBullet() {}
virtual PhysicsServer3D::JointType get_type() const = 0;
};
-#endif
+
+#endif // JOINT_BULLET_H
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index 03853cc830..72fdd5c408 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -35,10 +35,6 @@
#include <BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h>
-/**
- @author AndreaCatania
-*/
-
PinJointBullet::PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b) :
JointBullet() {
if (p_body_b) {
diff --git a/modules/bullet/pin_joint_bullet.h b/modules/bullet/pin_joint_bullet.h
index 0510cf99ad..0a688d55f9 100644
--- a/modules/bullet/pin_joint_bullet.h
+++ b/modules/bullet/pin_joint_bullet.h
@@ -33,10 +33,6 @@
#include "joint_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class PinJointBullet : public JointBullet {
@@ -57,4 +53,5 @@ public:
Vector3 getPivotInA();
Vector3 getPivotInB();
};
-#endif
+
+#endif // PIN_JOINT_BULLET_H
diff --git a/modules/bullet/register_types.cpp b/modules/bullet/register_types.cpp
index 675a5c8491..d5d0ee2cf4 100644
--- a/modules/bullet/register_types.cpp
+++ b/modules/bullet/register_types.cpp
@@ -34,10 +34,6 @@
#include "core/config/project_settings.h"
#include "core/object/class_db.h"
-/**
- @author AndreaCatania
-*/
-
#ifndef _3D_DISABLED
PhysicsServer3D *_createBulletPhysicsCallback() {
return memnew(BulletPhysicsServer3D);
diff --git a/modules/bullet/register_types.h b/modules/bullet/register_types.h
index 739614dc52..93847d6dc3 100644
--- a/modules/bullet/register_types.h
+++ b/modules/bullet/register_types.h
@@ -31,10 +31,7 @@
#ifndef REGISTER_BULLET_TYPES_H
#define REGISTER_BULLET_TYPES_H
-/**
- @author AndreaCatania
-*/
-
void register_bullet_types();
void unregister_bullet_types();
-#endif
+
+#endif // REGISTER_BULLET_TYPES_H
diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h
index 982654441e..260d303cac 100644
--- a/modules/bullet/rid_bullet.h
+++ b/modules/bullet/rid_bullet.h
@@ -33,10 +33,6 @@
#include "core/templates/rid.h"
-/**
- @author AndreaCatania
-*/
-
class BulletPhysicsServer3D;
class RIDBullet {
@@ -50,4 +46,5 @@ public:
_FORCE_INLINE_ void _set_physics_server(BulletPhysicsServer3D *p_physicsServer) { physicsServer = p_physicsServer; }
_FORCE_INLINE_ BulletPhysicsServer3D *get_physics_server() const { return physicsServer; }
};
-#endif
+
+#endif // RID_BULLET_H
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index 0112712736..0603963332 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -42,12 +42,6 @@
#include <BulletDynamics/Dynamics/btRigidBody.h>
#include <btBulletCollisionCommon.h>
-#include <assert.h>
-
-/**
- @author AndreaCatania
-*/
-
BulletPhysicsDirectBodyState3D *BulletPhysicsDirectBodyState3D::singleton = nullptr;
Vector3 BulletPhysicsDirectBodyState3D::get_total_gravity() const {
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index f41c5ca1c9..cd433c968f 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef BODYBULLET_H
-#define BODYBULLET_H
+#ifndef RIGID_BODY_BULLET_H
+#define RIGID_BODY_BULLET_H
#include "collision_object_bullet.h"
#include "space_bullet.h"
@@ -37,10 +37,6 @@
#include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h>
#include <LinearMath/btTransform.h>
-/**
- @author AndreaCatania
-*/
-
class AreaBullet;
class SpaceBullet;
class btRigidBody;
@@ -329,4 +325,4 @@ private:
void _internal_set_mass(real_t p_mass);
};
-#endif
+#endif // RIGID_BODY_BULLET_H
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 2b2a7dd8f1..77a583ad86 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -42,10 +42,6 @@
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include <btBulletCollisionCommon.h>
-/**
- @author AndreaCatania
-*/
-
ShapeBullet::ShapeBullet() {}
ShapeBullet::~ShapeBullet() {}
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 93e9bed201..6377f8915d 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -40,10 +40,6 @@
#include <LinearMath/btScalar.h>
#include <LinearMath/btVector3.h>
-/**
- @author AndreaCatania
-*/
-
class ShapeBullet;
class btCollisionShape;
class ShapeOwnerBullet;
@@ -244,4 +240,5 @@ public:
private:
void setup(real_t p_length, bool p_slips_on_slope);
};
-#endif
+
+#endif // SHAPE_BULLET_H
diff --git a/modules/bullet/shape_owner_bullet.cpp b/modules/bullet/shape_owner_bullet.cpp
deleted file mode 100644
index 7f516e83c0..0000000000
--- a/modules/bullet/shape_owner_bullet.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*************************************************************************/
-/* shape_owner_bullet.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 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 "shape_owner_bullet.h"
-
-/**
- @author AndreaCatania
-*/
diff --git a/modules/bullet/shape_owner_bullet.h b/modules/bullet/shape_owner_bullet.h
index 5f8bb61503..11cf1bc2d5 100644
--- a/modules/bullet/shape_owner_bullet.h
+++ b/modules/bullet/shape_owner_bullet.h
@@ -33,10 +33,6 @@
#include "rid_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class ShapeBullet;
class btCollisionShape;
class CollisionObjectBullet;
@@ -51,4 +47,5 @@ public:
virtual void remove_shape_full(class ShapeBullet *p_shape) = 0;
virtual ~ShapeOwnerBullet() {}
};
-#endif
+
+#endif // SHAPE_OWNER_BULLET_H
diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp
index a3190609a1..61c3b3b0a3 100644
--- a/modules/bullet/slider_joint_bullet.cpp
+++ b/modules/bullet/slider_joint_bullet.cpp
@@ -36,10 +36,6 @@
#include <BulletDynamics/ConstraintSolver/btSliderConstraint.h>
-/**
- @author AndreaCatania
-*/
-
SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
JointBullet() {
Transform3D scaled_AFrame(frameInA.scaled(rbA->get_body_scale()));
diff --git a/modules/bullet/slider_joint_bullet.h b/modules/bullet/slider_joint_bullet.h
index 556f4e9e64..c355eb340b 100644
--- a/modules/bullet/slider_joint_bullet.h
+++ b/modules/bullet/slider_joint_bullet.h
@@ -33,10 +33,6 @@
#include "joint_bullet.h"
-/**
- @author AndreaCatania
-*/
-
class RigidBodyBullet;
class SliderJointBullet : public JointBullet {
@@ -118,4 +114,5 @@ public:
void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value);
real_t get_param(PhysicsServer3D::SliderJointParam p_param) const;
};
-#endif
+
+#endif // SLIDER_JOINT_BULLET_H
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
index fea26e9449..82a7bb3b0c 100644
--- a/modules/bullet/soft_body_bullet.h
+++ b/modules/bullet/soft_body_bullet.h
@@ -49,10 +49,6 @@
#define None 0L
#endif
-/**
- @author AndreaCatania
-*/
-
class RenderingServerHandler;
class SoftBodyBullet : public CollisionObjectBullet {
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 55e822ba5a..460b78d778 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -54,10 +54,6 @@
#include <assert.h>
-/**
- @author AndreaCatania
-*/
-
BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_space) :
PhysicsDirectSpaceState3D(),
space(p_space) {}
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index 154bb6f01b..f858c5fcb5 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -43,10 +43,6 @@
#include <LinearMath/btTransform.h>
#include <LinearMath/btVector3.h>
-/**
- @author AndreaCatania
-*/
-
class AreaBullet;
class btBroadphaseInterface;
class btCollisionDispatcher;
@@ -220,4 +216,5 @@ private:
int add_separation_result(PhysicsServer3D::SeparationResult *r_results, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const;
int recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results);
};
-#endif
+
+#endif // SPACE_BULLET_H
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index 71891c8704..9a6a33fad3 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -50,7 +50,7 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
create_handle_material("handles");
}
-String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@@ -72,7 +72,7 @@ String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo,
return "";
}
-Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
+Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@@ -98,7 +98,7 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo
return Variant();
}
-void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
+void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
Transform3D gt = cs->get_global_transform();
@@ -201,7 +201,7 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i
}
}
-void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
+void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@@ -343,6 +343,16 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
+ Array csg_meshes = cs->get_meshes();
+ if (csg_meshes.size() != 2) {
+ return;
+ }
+
+ Ref<Mesh> csg_mesh = csg_meshes[1];
+ if (csg_mesh.is_valid()) {
+ p_gizmo->add_collision_triangles(csg_mesh->generate_triangle_mesh());
+ }
+
if (p_gizmo->is_selected()) {
// Draw a translucent representation of the CSG node
Ref<ArrayMesh> mesh = memnew(ArrayMesh);
diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h
index 1dcee642c7..46761370dd 100644
--- a/modules/csg/csg_gizmos.h
+++ b/modules/csg/csg_gizmos.h
@@ -45,10 +45,10 @@ public:
virtual bool is_selectable_when_hidden() const override;
virtual void redraw(EditorNode3DGizmo *p_gizmo) override;
- virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const override;
- virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) override;
- virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) override;
+ virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
+ virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
+ virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) override;
CSGShape3DGizmoPlugin();
};
diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp
index 2b29f4d97e..643a74f83e 100644
--- a/modules/fbx/data/fbx_mesh_data.cpp
+++ b/modules/fbx/data/fbx_mesh_data.cpp
@@ -1092,7 +1092,7 @@ HashMap<int, R> FBXMeshData::extract_per_vertex_data(
const int vertex_index = get_vertex_from_polygon_vertex(p_mesh_indices, polygon_vertex_index);
ERR_FAIL_COND_V_MSG(vertex_index < 0, (HashMap<int, R>()), "FBX file corrupted: #ERR05");
ERR_FAIL_COND_V_MSG(vertex_index >= p_vertex_count, (HashMap<int, R>()), "FBX file corrupted: #ERR06");
- const int index_to_direct = p_mapping_data.index[polygon_vertex_index];
+ const int index_to_direct = get_vertex_from_polygon_vertex(p_mapping_data.index, polygon_vertex_index);
T value = p_mapping_data.data[index_to_direct];
aggregate_vertex_data[vertex_index].push_back({ polygon_id, value });
}
@@ -1297,7 +1297,7 @@ HashMap<int, T> FBXMeshData::extract_per_polygon(
} else {
ERR_FAIL_INDEX_V_MSG(polygon_index, (int)p_fbx_data.index.size(), (HashMap<int, T>()), "FBX file is corrupted: #ERR62");
- const int index_to_direct = p_fbx_data.index[polygon_index];
+ const int index_to_direct = get_vertex_from_polygon_vertex(p_fbx_data.index, polygon_index);
T value = p_fbx_data.data[index_to_direct];
aggregate_polygon_data[polygon_index].push_back(value);
}
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 0bf4f5e1f1..3a79190149 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1868,13 +1868,14 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
push_error("Cannot assign a new value to a constant.", p_assignment->assignee);
}
- if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) {
- bool compatible = true;
- GDScriptParser::DataType op_type = assigned_value_type;
- if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
- op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value);
- }
+ bool compatible = true;
+ GDScriptParser::DataType op_type = assigned_value_type;
+ if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
+ op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value);
+ }
+ p_assignment->set_datatype(op_type);
+ if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) {
if (compatible) {
compatible = is_type_compatible(assignee_type, op_type, true);
if (!compatible) {
@@ -1899,7 +1900,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
if (assignee_type.has_no_type() || assigned_value_type.is_variant()) {
mark_node_unsafe(p_assignment);
- if (assignee_type.is_hard_type()) {
+ if (assignee_type.is_hard_type() && !assignee_type.is_variant()) {
p_assignment->use_conversion_assign = true;
}
}
@@ -3787,6 +3788,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
// Unary version.
GDScriptParser::DataType nil_type;
nil_type.builtin_type = Variant::NIL;
+ nil_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
return get_operation_type(p_operation, p_a, nil_type, r_valid, p_source);
}
@@ -3796,20 +3798,31 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator
Variant::Type a_type = p_a.builtin_type;
Variant::Type b_type = p_b.builtin_type;
-
Variant::ValidatedOperatorEvaluator op_eval = Variant::get_validated_operator_evaluator(p_operation, a_type, b_type);
- if (op_eval == nullptr) {
+ bool hard_operation = p_a.is_hard_type() && p_b.is_hard_type();
+ bool validated = op_eval != nullptr;
+
+ if (hard_operation && !validated) {
r_valid = false;
return result;
+ } else if (hard_operation && validated) {
+ r_valid = true;
+ result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
+ result.kind = GDScriptParser::DataType::BUILTIN;
+ result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type);
+ } else if (!hard_operation && !validated) {
+ r_valid = true;
+ result.type_source = GDScriptParser::DataType::UNDETECTED;
+ result.kind = GDScriptParser::DataType::VARIANT;
+ result.builtin_type = Variant::NIL;
+ } else if (!hard_operation && validated) {
+ r_valid = true;
+ result.type_source = GDScriptParser::DataType::INFERRED;
+ result.kind = GDScriptParser::DataType::BUILTIN;
+ result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type);
}
- r_valid = true;
- result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
-
- result.kind = GDScriptParser::DataType::BUILTIN;
- result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type);
-
return result;
}
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index af5ada513c..117ca68c18 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -882,7 +882,13 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
#endif
/* Find chain of sets */
- StringName assign_property;
+ StringName assign_class_member_property;
+
+ GDScriptCodeGenerator::Address target_member_property;
+ bool is_member_property = false;
+ bool member_property_has_setter = false;
+ bool member_property_is_in_setter = false;
+ StringName member_property_setter_function;
List<const GDScriptParser::SubscriptNode *> chain;
@@ -892,11 +898,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
while (true) {
chain.push_back(n);
if (n->base->type != GDScriptParser::Node::SUBSCRIPT) {
- // Check for a built-in property.
+ // Check for a 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)) {
- assign_property = identifier->name;
+ StringName var_name = identifier->name;
+ if (_is_class_member_property(codegen, var_name)) {
+ assign_class_member_property = var_name;
+ } else if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) {
+ is_member_property = true;
+ member_property_setter_function = codegen.script->member_indices[var_name].setter;
+ member_property_has_setter = member_property_setter_function != StringName();
+ member_property_is_in_setter = member_property_has_setter && member_property_setter_function == codegen.function_name;
+ target_member_property.mode = GDScriptCodeGenerator::Address::MEMBER;
+ target_member_property.address = codegen.script->member_indices[var_name].index;
+ target_member_property.type = codegen.script->member_indices[var_name].data_type;
}
}
break;
@@ -969,17 +984,19 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
// Perform operator if any.
if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
+ GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype()));
GDScriptCodeGenerator::Address value = codegen.add_temporary(_gdtype_from_datatype(subscript->get_datatype()));
if (subscript->is_attribute) {
gen->write_get_named(value, name, prev_base);
} else {
gen->write_get(value, key, prev_base);
}
- gen->write_binary_operator(value, assignment->variant_op, value, assigned);
+ gen->write_binary_operator(op_result, assignment->variant_op, value, assigned);
+ gen->pop_temporary();
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
}
- assigned = value;
+ assigned = op_result;
}
// Perform assignment.
@@ -1013,10 +1030,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
assigned = info.base;
}
- // If this is a local member, also assign to it.
+ // If this is a class member property, also assign to it.
// This allow things like: position.x += 2.0
- if (assign_property != StringName()) {
- gen->write_set_member(assigned, assign_property);
+ if (assign_class_member_property != StringName()) {
+ gen->write_set_member(assigned, assign_class_member_property);
+ }
+ // Same as above but for members
+ if (is_member_property) {
+ if (member_property_has_setter && !member_property_is_in_setter) {
+ Vector<GDScriptCodeGenerator::Address> args;
+ args.push_back(assigned);
+ gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), member_property_setter_function, args);
+ } else {
+ gen->write_assign(target_member_property, assigned);
+ }
}
if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
@@ -1035,8 +1062,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
if (has_operation) {
- GDScriptCodeGenerator::Address op_result = codegen.add_temporary();
- GDScriptCodeGenerator::Address member = codegen.add_temporary();
+ GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype()));
+ GDScriptCodeGenerator::Address member = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype()));
gen->write_get_member(member, name);
gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value);
gen->pop_temporary(); // Pop member temp.
@@ -1053,29 +1080,26 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
}
} else {
// Regular assignment.
- GDScriptCodeGenerator::Address target;
-
+ ERR_FAIL_COND_V_MSG(assignment->assignee->type != GDScriptParser::Node::IDENTIFIER, GDScriptCodeGenerator::Address(), "Expected the assignee to be an identifier here.");
+ GDScriptCodeGenerator::Address member;
+ bool is_member = false;
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.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;
- target.mode = GDScriptCodeGenerator::Address::MEMBER;
- target.address = codegen.script->member_indices[var_name].index;
- }
- }
+ StringName var_name = static_cast<const GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
+ if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) {
+ is_member = true;
+ setter_function = codegen.script->member_indices[var_name].setter;
+ has_setter = setter_function != StringName();
+ is_in_setter = has_setter && setter_function == codegen.function_name;
+ member.mode = GDScriptCodeGenerator::Address::MEMBER;
+ member.address = codegen.script->member_indices[var_name].index;
+ member.type = codegen.script->member_indices[var_name].data_type;
}
- if (has_setter) {
- if (!is_in_setter) {
- // Store stack slot for the temp value.
- target = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype()));
- }
+ GDScriptCodeGenerator::Address target;
+ if (is_member) {
+ target = member; // _parse_expression could call its getter, but we want to know the actual address
} else {
target = _parse_expression(codegen, r_error, assignment->assignee);
if (r_error) {
@@ -1092,7 +1116,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE;
if (has_operation) {
// Perform operation.
- GDScriptCodeGenerator::Address op_result = codegen.add_temporary();
+ GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype()));
GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee);
gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value);
to_assign = op_result;
@@ -2069,7 +2093,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
if (p_func) {
// if no return statement -> return type is void not unresolved Variant
if (p_func->body->has_return) {
- gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype());
+ gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script);
} else {
gd_function->return_type = GDScriptDataType();
gd_function->return_type.has_type = true;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 9db76861ff..7c27a096e7 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -580,12 +580,50 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio
if (par->default_value) {
String def_val = "<unknown>";
- if (par->default_value->type == GDScriptParser::Node::LITERAL) {
- const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(par->default_value);
- def_val = literal->value.get_construct_string();
- } else if (par->default_value->type == GDScriptParser::Node::IDENTIFIER) {
- const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(par->default_value);
- def_val = id->name.operator String();
+ switch (par->default_value->type) {
+ case GDScriptParser::Node::LITERAL: {
+ const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(par->default_value);
+ def_val = literal->value.get_construct_string();
+ } break;
+ case GDScriptParser::Node::IDENTIFIER: {
+ const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(par->default_value);
+ def_val = id->name.operator String();
+ } break;
+ case GDScriptParser::Node::CALL: {
+ const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(par->default_value);
+ if (call->is_constant && call->reduced) {
+ def_val = call->function_name.operator String() + call->reduced_value.operator String();
+ }
+ } break;
+ case GDScriptParser::Node::ARRAY: {
+ const GDScriptParser::ArrayNode *arr = static_cast<const GDScriptParser::ArrayNode *>(par->default_value);
+ if (arr->is_constant && arr->reduced) {
+ def_val = arr->reduced_value.operator String();
+ }
+ } break;
+ case GDScriptParser::Node::DICTIONARY: {
+ const GDScriptParser::DictionaryNode *dict = static_cast<const GDScriptParser::DictionaryNode *>(par->default_value);
+ if (dict->is_constant && dict->reduced) {
+ def_val = dict->reduced_value.operator String();
+ }
+ } break;
+ case GDScriptParser::Node::SUBSCRIPT: {
+ const GDScriptParser::SubscriptNode *sub = static_cast<const GDScriptParser::SubscriptNode *>(par->default_value);
+ if (sub->is_constant) {
+ if (sub->datatype.kind == GDScriptParser::DataType::ENUM_VALUE) {
+ def_val = sub->get_datatype().to_string();
+ } else if (sub->reduced) {
+ const Variant::Type vt = sub->reduced_value.get_type();
+ if (vt == Variant::Type::NIL || vt == Variant::Type::FLOAT || vt == Variant::Type::INT || vt == Variant::Type::STRING || vt == Variant::Type::STRING_NAME || vt == Variant::Type::BOOL || vt == Variant::Type::NODE_PATH) {
+ def_val = sub->reduced_value.operator String();
+ } else {
+ def_val = sub->get_datatype().to_string() + sub->reduced_value.operator String();
+ }
+ }
+ }
+ } break;
+ default:
+ break;
}
arghint += " = " + def_val;
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 2faf0febca..432d31f78f 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -817,6 +817,8 @@ void GDScriptParser::parse_class_body(bool p_is_multiline) {
class_end = true;
break;
default:
+ // Display a completion with identifiers.
+ make_completion_context(COMPLETION_IDENTIFIER, nullptr);
push_error(vformat(R"(Unexpected "%s" in class body.)", current.get_name()));
advance();
break;
@@ -3537,12 +3539,12 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
variable->export_info.hint = PROPERTY_HINT_ENUM;
String enum_hint_string;
- for (const Map<StringName, int>::Element *E = export_type.enum_values.front(); E; E = E->next()) {
- enum_hint_string += E->key().operator String().capitalize().xml_escape();
+ for (OrderedHashMap<StringName, int>::Element E = export_type.enum_values.front(); E; E = E.next()) {
+ enum_hint_string += E.key().operator String().capitalize().xml_escape();
enum_hint_string += ":";
- enum_hint_string += String::num_int64(E->get()).xml_escape();
+ enum_hint_string += String::num_int64(E.value()).xml_escape();
- if (E->next()) {
+ if (E.next()) {
enum_hint_string += ",";
}
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index bf0f670905..e4311d2d5e 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -133,7 +133,7 @@ public:
ClassNode *class_type = nullptr;
MethodInfo method_info; // For callable/signals.
- Map<StringName, int> enum_values; // For enums.
+ OrderedHashMap<StringName, int> enum_values; // For enums.
_FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; }
_FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 014a2ad3b8..e0facaf61d 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -488,7 +488,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
memnew_placement(&stack[i + 3], Variant(*p_args[i]));
continue;
}
-
+ // If types already match, don't call Variant::construct(). Constructors of some types
+ // (e.g. packed arrays) do copies, whereas they pass by reference when inside a Variant.
+ if (argument_types[i].is_type(*p_args[i], false)) {
+ memnew_placement(&stack[i + 3], Variant(*p_args[i]));
+ continue;
+ }
if (!argument_types[i].is_type(*p_args[i], true)) {
r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_err.argument = i;
diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub
index 1954a32697..22ef1b5ea9 100644
--- a/modules/glslang/SCsub
+++ b/modules/glslang/SCsub
@@ -12,7 +12,6 @@ thirdparty_obj = []
if env["builtin_glslang"]:
thirdparty_dir = "#thirdparty/glslang/"
thirdparty_sources = [
- "glslang/CInterface/glslang_c_interface.cpp",
"glslang/MachineIndependent/attribute.cpp",
"glslang/MachineIndependent/Constant.cpp",
"glslang/MachineIndependent/glslang_tab.cpp",
@@ -44,7 +43,6 @@ if env["builtin_glslang"]:
"glslang/GenericCodeGen/CodeGen.cpp",
"glslang/GenericCodeGen/Link.cpp",
"OGLCompilersDLL/InitializeDll.cpp",
- "SPIRV/CInterface/spirv_c_interface.cpp",
"SPIRV/disassemble.cpp",
"SPIRV/doc.cpp",
"SPIRV/GlslangToSpv.cpp",
@@ -54,7 +52,6 @@ if env["builtin_glslang"]:
"SPIRV/SpvPostProcess.cpp",
"SPIRV/SPVRemapper.cpp",
"SPIRV/SpvTools.cpp",
- "StandAlone/ResourceLimits.cpp",
]
if env["platform"] == "windows":
@@ -65,10 +62,12 @@ if env["builtin_glslang"]:
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
# Treat glslang headers as system headers to avoid raising warnings. Not supported on MSVC.
+ # Include `#thirdparty` to workaround mismatch between location of `SPIRV` in library source
+ # and in installed public headers.
if not env.msvc:
- env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path])
+ env_glslang.Append(CPPFLAGS=["-isystem", Dir(thirdparty_dir).path, "-isystem", Dir("#thirdparty").path])
else:
- env_glslang.Prepend(CPPPATH=[thirdparty_dir])
+ env_glslang.Prepend(CPPPATH=[thirdparty_dir, "#thirdparty"])
env_glslang.Append(CPPDEFINES=["ENABLE_OPT=0"])
diff --git a/modules/glslang/glslang_resource_limits.h b/modules/glslang/glslang_resource_limits.h
new file mode 100644
index 0000000000..05390f95ad
--- /dev/null
+++ b/modules/glslang/glslang_resource_limits.h
@@ -0,0 +1,147 @@
+/*************************************************************************/
+/* glslang_resource_limits.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 GLSLANG_RESOURCE_LIMITS_H
+#define GLSLANG_RESOURCE_LIMITS_H
+
+#include <glslang/Include/ResourceLimits.h>
+
+// Synchronized with upstream glslang/StandAlone/ResourceLimits.cpp which is not
+// part of the public API.
+
+const TBuiltInResource DefaultTBuiltInResource = {
+ /* .MaxLights = */ 32,
+ /* .MaxClipPlanes = */ 6,
+ /* .MaxTextureUnits = */ 32,
+ /* .MaxTextureCoords = */ 32,
+ /* .MaxVertexAttribs = */ 64,
+ /* .MaxVertexUniformComponents = */ 4096,
+ /* .MaxVaryingFloats = */ 64,
+ /* .MaxVertexTextureImageUnits = */ 32,
+ /* .MaxCombinedTextureImageUnits = */ 80,
+ /* .MaxTextureImageUnits = */ 32,
+ /* .MaxFragmentUniformComponents = */ 4096,
+ /* .MaxDrawBuffers = */ 32,
+ /* .MaxVertexUniformVectors = */ 128,
+ /* .MaxVaryingVectors = */ 8,
+ /* .MaxFragmentUniformVectors = */ 16,
+ /* .MaxVertexOutputVectors = */ 16,
+ /* .MaxFragmentInputVectors = */ 15,
+ /* .MinProgramTexelOffset = */ -8,
+ /* .MaxProgramTexelOffset = */ 7,
+ /* .MaxClipDistances = */ 8,
+ /* .MaxComputeWorkGroupCountX = */ 65535,
+ /* .MaxComputeWorkGroupCountY = */ 65535,
+ /* .MaxComputeWorkGroupCountZ = */ 65535,
+ /* .MaxComputeWorkGroupSizeX = */ 1024,
+ /* .MaxComputeWorkGroupSizeY = */ 1024,
+ /* .MaxComputeWorkGroupSizeZ = */ 64,
+ /* .MaxComputeUniformComponents = */ 1024,
+ /* .MaxComputeTextureImageUnits = */ 16,
+ /* .MaxComputeImageUniforms = */ 8,
+ /* .MaxComputeAtomicCounters = */ 8,
+ /* .MaxComputeAtomicCounterBuffers = */ 1,
+ /* .MaxVaryingComponents = */ 60,
+ /* .MaxVertexOutputComponents = */ 64,
+ /* .MaxGeometryInputComponents = */ 64,
+ /* .MaxGeometryOutputComponents = */ 128,
+ /* .MaxFragmentInputComponents = */ 128,
+ /* .MaxImageUnits = */ 8,
+ /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
+ /* .MaxCombinedShaderOutputResources = */ 8,
+ /* .MaxImageSamples = */ 0,
+ /* .MaxVertexImageUniforms = */ 0,
+ /* .MaxTessControlImageUniforms = */ 0,
+ /* .MaxTessEvaluationImageUniforms = */ 0,
+ /* .MaxGeometryImageUniforms = */ 0,
+ /* .MaxFragmentImageUniforms = */ 8,
+ /* .MaxCombinedImageUniforms = */ 8,
+ /* .MaxGeometryTextureImageUnits = */ 16,
+ /* .MaxGeometryOutputVertices = */ 256,
+ /* .MaxGeometryTotalOutputComponents = */ 1024,
+ /* .MaxGeometryUniformComponents = */ 1024,
+ /* .MaxGeometryVaryingComponents = */ 64,
+ /* .MaxTessControlInputComponents = */ 128,
+ /* .MaxTessControlOutputComponents = */ 128,
+ /* .MaxTessControlTextureImageUnits = */ 16,
+ /* .MaxTessControlUniformComponents = */ 1024,
+ /* .MaxTessControlTotalOutputComponents = */ 4096,
+ /* .MaxTessEvaluationInputComponents = */ 128,
+ /* .MaxTessEvaluationOutputComponents = */ 128,
+ /* .MaxTessEvaluationTextureImageUnits = */ 16,
+ /* .MaxTessEvaluationUniformComponents = */ 1024,
+ /* .MaxTessPatchComponents = */ 120,
+ /* .MaxPatchVertices = */ 32,
+ /* .MaxTessGenLevel = */ 64,
+ /* .MaxViewports = */ 16,
+ /* .MaxVertexAtomicCounters = */ 0,
+ /* .MaxTessControlAtomicCounters = */ 0,
+ /* .MaxTessEvaluationAtomicCounters = */ 0,
+ /* .MaxGeometryAtomicCounters = */ 0,
+ /* .MaxFragmentAtomicCounters = */ 8,
+ /* .MaxCombinedAtomicCounters = */ 8,
+ /* .MaxAtomicCounterBindings = */ 1,
+ /* .MaxVertexAtomicCounterBuffers = */ 0,
+ /* .MaxTessControlAtomicCounterBuffers = */ 0,
+ /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
+ /* .MaxGeometryAtomicCounterBuffers = */ 0,
+ /* .MaxFragmentAtomicCounterBuffers = */ 1,
+ /* .MaxCombinedAtomicCounterBuffers = */ 1,
+ /* .MaxAtomicCounterBufferSize = */ 16384,
+ /* .MaxTransformFeedbackBuffers = */ 4,
+ /* .MaxTransformFeedbackInterleavedComponents = */ 64,
+ /* .MaxCullDistances = */ 8,
+ /* .MaxCombinedClipAndCullDistances = */ 8,
+ /* .MaxSamples = */ 4,
+ /* .maxMeshOutputVerticesNV = */ 256,
+ /* .maxMeshOutputPrimitivesNV = */ 512,
+ /* .maxMeshWorkGroupSizeX_NV = */ 32,
+ /* .maxMeshWorkGroupSizeY_NV = */ 1,
+ /* .maxMeshWorkGroupSizeZ_NV = */ 1,
+ /* .maxTaskWorkGroupSizeX_NV = */ 32,
+ /* .maxTaskWorkGroupSizeY_NV = */ 1,
+ /* .maxTaskWorkGroupSizeZ_NV = */ 1,
+ /* .maxMeshViewCountNV = */ 4,
+ /* .maxDualSourceDrawBuffersEXT = */ 1,
+
+ /* .limits = */ {
+ /* .nonInductiveForLoops = */ 1,
+ /* .whileLoops = */ 1,
+ /* .doWhileLoops = */ 1,
+ /* .generalUniformIndexing = */ 1,
+ /* .generalAttributeMatrixVectorIndexing = */ 1,
+ /* .generalVaryingIndexing = */ 1,
+ /* .generalSamplerIndexing = */ 1,
+ /* .generalVariableIndexing = */ 1,
+ /* .generalConstantMatrixVectorIndexing = */ 1,
+ }
+};
+
+#endif // GLSLANG_RESOURCE_LIMITS_H
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index c67d5ff5ab..8e69ba78c7 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -32,10 +32,11 @@
#include "servers/rendering/rendering_device.h"
-#include <SPIRV/GlslangToSpv.h>
-#include <StandAlone/ResourceLimits.h>
+#include "glslang_resource_limits.h"
+
#include <glslang/Include/Types.h>
#include <glslang/Public/ShaderLang.h>
+#include <glslang/SPIRV/GlslangToSpv.h>
static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice::Capabilities *p_capabilities) {
Vector<uint8_t> ret;
@@ -129,7 +130,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
std::string pre_processed_code;
//preprocess
- if (!shader.preprocess(&glslang::DefaultTBuiltInResource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) {
+ if (!shader.preprocess(&DefaultTBuiltInResource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) {
if (r_error) {
(*r_error) = "Failed pre-process:\n";
(*r_error) += shader.getInfoLog();
@@ -144,7 +145,7 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
shader.setStrings(&cs_strings, 1);
//parse
- if (!shader.parse(&glslang::DefaultTBuiltInResource, DefaultVersion, false, messages)) {
+ if (!shader.parse(&DefaultTBuiltInResource, DefaultVersion, false, messages)) {
if (r_error) {
(*r_error) = "Failed parse:\n";
(*r_error) += shader.getInfoLog();
@@ -190,8 +191,8 @@ static String _get_cache_key_function_glsl(const RenderingDevice::Capabilities *
}
void preregister_glslang_types() {
- // initialize in case it's not initialized. This is done once per thread
- // and it's safe to call multiple times
+ // Initialize in case it's not initialized. This is done once per thread
+ // and it's safe to call multiple times.
glslang::InitializeProcess();
RenderingDevice::shader_set_compile_to_spirv_function(_compile_shader_glsl);
RenderingDevice::shader_set_get_cache_key_function(_get_cache_key_function_glsl);
diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub
index 4fcbe8fb43..9133fdef35 100644
--- a/modules/mbedtls/SCsub
+++ b/modules/mbedtls/SCsub
@@ -29,6 +29,7 @@ if env["builtin_mbedtls"]:
"cipher_wrap.c",
"cmac.c",
"ctr_drbg.c",
+ "constant_time.c",
"debug.c",
"des.c",
"dhm.c",
@@ -48,8 +49,9 @@ if env["builtin_mbedtls"]:
"md4.c",
"md5.c",
"md.c",
- "md_wrap.c",
"memory_buffer_alloc.c",
+ "mps_reader.c",
+ "mps_trace.c",
"net_sockets.c",
"nist_kw.c",
"oid.c",
@@ -75,9 +77,11 @@ if env["builtin_mbedtls"]:
"ssl_ciphersuites.c",
"ssl_cli.c",
"ssl_cookie.c",
+ "ssl_msg.c",
"ssl_srv.c",
"ssl_ticket.c",
"ssl_tls.c",
+ "ssl_tls13_keys.c",
"threading.c",
"timing.c",
"version.c",
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index 9fcac3afe2..ac04763569 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -35,8 +35,6 @@
#include "servers/xr/xr_positional_tracker.h"
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The mobile interface is a native VR interface that can be used on Android and iOS phones.
It contains a basic implementation supporting 3DOF tracking if a gyroscope and accelerometer are
present and sets up the proper projection matrices based on the values provided.
@@ -160,4 +158,4 @@ public:
~MobileVRInterface();
};
-#endif // !MOBILE_VR_INTERFACE_H
+#endif // MOBILE_VR_INTERFACE_H
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index 2b6ae5ef1e..f3da85063a 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -36,10 +36,6 @@
#include "navigation_mesh_generator.h"
#endif
-/**
- @author AndreaCatania
-*/
-
/// Creates a struct for each function and a function that once called creates
/// an instance of that struct with the submitted parameters.
/// Then, that struct is stored in an array; the `sync` function consume that array.
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index 6cc226b086..c555a358db 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -40,10 +40,6 @@
#include "nav_region.h"
#include "rvo_agent.h"
-/**
- @author AndreaCatania
-*/
-
/// The commands are functions executed during the `sync` phase.
#define MERGE_INTERNAL(A, B) A##B
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index b33b7933a8..76c31a5f42 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -36,10 +36,6 @@
#include <algorithm>
-/**
- @author AndreaCatania
-*/
-
#define THREE_POINTS_CROSS_PRODUCT(m_a, m_b, m_c) (((m_c) - (m_a)).cross((m_b) - (m_a)))
void NavMap::set_up(Vector3 p_up) {
diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h
index cd730fe3ef..1802f4e907 100644
--- a/modules/navigation/nav_map.h
+++ b/modules/navigation/nav_map.h
@@ -36,11 +36,8 @@
#include "core/math/math_defs.h"
#include "core/templates/map.h"
#include "nav_utils.h"
-#include <KdTree.h>
-/**
- @author AndreaCatania
-*/
+#include <KdTree.h>
class NavRegion;
class RvoAgent;
diff --git a/modules/navigation/nav_region.cpp b/modules/navigation/nav_region.cpp
index 7d94e22014..fea0ad519a 100644
--- a/modules/navigation/nav_region.cpp
+++ b/modules/navigation/nav_region.cpp
@@ -32,10 +32,6 @@
#include "nav_map.h"
-/**
- @author AndreaCatania
-*/
-
void NavRegion::set_map(NavMap *p_map) {
map = p_map;
polygons_dirty = true;
diff --git a/modules/navigation/nav_region.h b/modules/navigation/nav_region.h
index c344414912..7a6da281c0 100644
--- a/modules/navigation/nav_region.h
+++ b/modules/navigation/nav_region.h
@@ -35,11 +35,8 @@
#include "nav_rid.h"
#include "nav_utils.h"
-#include <vector>
-/**
- @author AndreaCatania
-*/
+#include <vector>
class NavMap;
class NavRegion;
diff --git a/modules/navigation/nav_rid.h b/modules/navigation/nav_rid.h
index 2283973cac..31e20440d2 100644
--- a/modules/navigation/nav_rid.h
+++ b/modules/navigation/nav_rid.h
@@ -33,10 +33,6 @@
#include "core/templates/rid.h"
-/**
- @author AndreaCatania
-*/
-
class NavRid {
RID self;
diff --git a/modules/navigation/nav_utils.h b/modules/navigation/nav_utils.h
index 2d725f214c..a6f51a4698 100644
--- a/modules/navigation/nav_utils.h
+++ b/modules/navigation/nav_utils.h
@@ -35,10 +35,6 @@
#include <vector>
-/**
- @author AndreaCatania
-*/
-
class NavRegion;
namespace gd {
diff --git a/modules/navigation/rvo_agent.cpp b/modules/navigation/rvo_agent.cpp
index 6c38eaed0f..c967d0bf98 100644
--- a/modules/navigation/rvo_agent.cpp
+++ b/modules/navigation/rvo_agent.cpp
@@ -32,10 +32,6 @@
#include "nav_map.h"
-/**
- @author AndreaCatania
-*/
-
RvoAgent::RvoAgent() {
callback.id = ObjectID();
}
diff --git a/modules/navigation/rvo_agent.h b/modules/navigation/rvo_agent.h
index 2bf824186b..54baab404e 100644
--- a/modules/navigation/rvo_agent.h
+++ b/modules/navigation/rvo_agent.h
@@ -36,10 +36,6 @@
#include <Agent.h>
-/**
- @author AndreaCatania
-*/
-
class NavMap;
class RvoAgent : public NavRid {
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 6052bf9831..03307c319e 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -34,10 +34,6 @@
#include "core/io/image_loader.h"
#include "core/string/ustring.h"
-/**
- @author Daniel Ramirez <djrmuv@gmail.com>
-*/
-
// Forward declare and include thirdparty headers in .cpp.
struct NSVGrasterizer;
struct NSVGimage;
@@ -70,4 +66,4 @@ public:
ImageLoaderSVG();
};
-#endif
+#endif // IMAGE_LOADER_SVG_H
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index f1945f62cb..f9997a437f 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -2573,7 +2573,7 @@ int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, cha
return FT_Get_Char_Index(fd->cache[size]->face, p_char);
}
} else {
- return 0;
+ return (int32_t)p_char;
}
#else
return (int32_t)p_char;
@@ -2841,6 +2841,24 @@ Vector<String> TextServerAdvanced::font_get_script_support_overrides(RID p_font_
return out;
}
+void TextServerAdvanced::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) {
+ FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ ERR_FAIL_COND(!fd);
+
+ MutexLock lock(fd->mutex);
+ Vector2i size = _get_size(fd, 16);
+ ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
+ fd->feature_overrides = p_overrides;
+}
+
+Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(RID p_font_rid) const {
+ FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
+ ERR_FAIL_COND_V(!fd, Dictionary());
+
+ MutexLock lock(fd->mutex);
+ return fd->feature_overrides;
+}
+
Dictionary TextServerAdvanced::font_supported_feature_list(RID p_font_rid) const {
FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3668,6 +3686,12 @@ float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const PackedFloat3
const_cast<TextServerAdvanced *>(this)->shaped_text_update_breaks(p_shaped);
}
+ for (int i = 0; i < p_tab_stops.size(); i++) {
+ if (p_tab_stops[i] <= 0) {
+ return 0.f;
+ }
+ }
+
int tab_index = 0;
float off = 0.f;
@@ -4231,6 +4255,24 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char
return gl;
}
+_FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs) {
+ for (const Variant *ftr = p_source.next(nullptr); ftr != nullptr; ftr = p_source.next(ftr)) {
+ int32_t values = p_source[*ftr];
+ if (values >= 0) {
+ hb_feature_t feature;
+ if (ftr->get_type() == Variant::STRING) {
+ feature.tag = name_to_tag(*ftr);
+ } else {
+ feature.tag = *ftr;
+ }
+ feature.value = values;
+ feature.start = 0;
+ feature.end = -1;
+ r_ftrs.push_back(feature);
+ }
+ }
+}
+
void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index) {
int fs = p_sd->spans[p_span].font_size;
if (p_fb_index >= p_fonts.size()) {
@@ -4287,17 +4329,9 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star
hb_buffer_add_utf32(p_sd->hb_buffer, (const uint32_t *)p_sd->text.ptr(), p_sd->text.length(), p_start, p_end - p_start);
Vector<hb_feature_t> ftrs;
- for (const Variant *ftr = p_sd->spans[p_span].features.next(nullptr); ftr != nullptr; ftr = p_sd->spans[p_span].features.next(ftr)) {
- double values = p_sd->spans[p_span].features[*ftr];
- if (values >= 0) {
- hb_feature_t feature;
- feature.tag = *ftr;
- feature.value = values;
- feature.start = 0;
- feature.end = -1;
- ftrs.push_back(feature);
- }
- }
+ _add_featuers(font_get_opentype_feature_overrides(f), ftrs);
+ _add_featuers(p_sd->spans[p_span].features, ftrs);
+
hb_shape(hb_font, p_sd->hb_buffer, ftrs.is_empty() ? nullptr : &ftrs[0], ftrs.size());
unsigned int glyph_count = 0;
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index fb9446da9f..6ff9817dcf 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -187,6 +187,7 @@ class TextServerAdvanced : public TextServer {
Set<uint32_t> supported_scripts;
Dictionary supported_features;
Dictionary supported_varaitions;
+ Dictionary feature_overrides;
// Language/script support override.
Map<String, bool> language_support_overrides;
@@ -272,6 +273,7 @@ class TextServerAdvanced : public TextServer {
bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const;
void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index);
Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size);
+ _FORCE_INLINE_ void _add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs);
// HarfBuzz bitmap font interface.
@@ -447,6 +449,9 @@ public:
virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override;
virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override;
+ virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
+ virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
+
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 1f7c5427be..f28d174c5c 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -1995,6 +1995,24 @@ Vector<String> TextServerFallback::font_get_script_support_overrides(RID p_font_
return out;
}
+void TextServerFallback::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) {
+ FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ ERR_FAIL_COND(!fd);
+
+ MutexLock lock(fd->mutex);
+ Vector2i size = _get_size(fd, 16);
+ ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
+ fd->feature_overrides = p_overrides;
+}
+
+Dictionary TextServerFallback::font_get_opentype_feature_overrides(RID p_font_rid) const {
+ FontDataFallback *fd = font_owner.get_or_null(p_font_rid);
+ ERR_FAIL_COND_V(!fd, Dictionary());
+
+ MutexLock lock(fd->mutex);
+ return fd->feature_overrides;
+}
+
Dictionary TextServerFallback::font_supported_feature_list(RID p_font_rid) const {
return Dictionary();
}
@@ -2665,6 +2683,12 @@ float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat3
const_cast<TextServerFallback *>(this)->shaped_text_update_breaks(p_shaped);
}
+ for (int i = 0; i < p_tab_stops.size(); i++) {
+ if (p_tab_stops[i] <= 0) {
+ return 0.f;
+ }
+ }
+
int tab_index = 0;
float off = 0.f;
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index d47fa44f8f..9d1be50b04 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -150,6 +150,7 @@ class TextServerFallback : public TextServer {
bool face_init = false;
Dictionary supported_varaitions;
+ Dictionary feature_overrides;
// Language/script support override.
Map<String, bool> language_support_overrides;
@@ -357,6 +358,9 @@ public:
virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override;
virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override;
+ virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
+ virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
+
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index feaff5925f..282a2a1662 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -33,9 +33,6 @@
#include "core/io/image_loader.h"
-/**
- @author SaracenOne
-*/
class ImageLoaderTGA : public ImageFormatLoader {
enum tga_type_e {
TGA_TYPE_NO_DATA = 0,
@@ -81,4 +78,4 @@ public:
ImageLoaderTGA();
};
-#endif
+#endif // IMAGE_LOADER_TGA_H
diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp
index bc40f4f9b4..0436f90c4c 100644
--- a/modules/visual_script/editor/visual_script_editor.cpp
+++ b/modules/visual_script/editor/visual_script_editor.cpp
@@ -1973,7 +1973,7 @@ void VisualScriptEditor::input(const Ref<InputEvent> &p_event) {
// GUI input for VS Editor Plugin
Ref<InputEventMouseButton> key = p_event;
- if (key.is_valid() && !key->is_pressed()) {
+ if (key.is_valid() && key->is_pressed()) {
mouse_up_position = get_screen_position() + get_local_mouse_position();
}
}
@@ -1982,10 +1982,28 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> key = p_event;
if (key.is_valid() && key->is_pressed() && key->get_button_mask() == MouseButton::RIGHT) {
- saved_position = graph->get_local_mouse_position();
+ bool is_empty_selection = true;
- Point2 gpos = get_screen_position() + get_local_mouse_position();
- _generic_search(script->get_instance_base_type(), gpos);
+ for (int i = 0; i < graph->get_child_count(); i++) {
+ GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
+ if (gn && gn->is_selected()) {
+ is_empty_selection = false;
+ break;
+ }
+ }
+ if (is_empty_selection && clipboard->nodes.is_empty()) {
+ _generic_search(script->get_instance_base_type(), mouse_up_position);
+ } else {
+ popup_menu->set_item_disabled(int(EDIT_CUT_NODES), is_empty_selection);
+ popup_menu->set_item_disabled(int(EDIT_COPY_NODES), is_empty_selection);
+ popup_menu->set_item_disabled(int(EDIT_PASTE_NODES), clipboard->nodes.is_empty());
+ popup_menu->set_item_disabled(int(EDIT_DELETE_NODES), is_empty_selection);
+ popup_menu->set_item_disabled(int(EDIT_DUPLICATE_NODES), is_empty_selection);
+ popup_menu->set_item_disabled(int(EDIT_CLEAR_COPY_BUFFER), clipboard->nodes.is_empty());
+
+ popup_menu->set_position(mouse_up_position);
+ popup_menu->popup();
+ }
}
}
@@ -3753,6 +3771,11 @@ void VisualScriptEditor::_toggle_scripts_pressed() {
void VisualScriptEditor::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ graph->set_panning_scheme((GraphEdit::PanningScheme)EDITOR_GET("interface/editors/sub_editor_panning_scheme").operator int());
+ } break;
+
case NOTIFICATION_READY: {
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_graph), varray(-1), CONNECT_DEFERRED);
@@ -3868,6 +3891,9 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_
void VisualScriptEditor::_menu_option(int p_what) {
switch (p_what) {
+ case EDIT_ADD_NODE: {
+ _generic_search(script->get_instance_base_type(), mouse_up_position);
+ } break;
case EDIT_DELETE_NODES: {
_on_nodes_delete();
} break;
@@ -3908,6 +3934,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
case EDIT_PASTE_NODES: {
_on_nodes_paste();
} break;
+ case EDIT_DUPLICATE_NODES: {
+ _on_nodes_duplicate();
+ } break;
case EDIT_CREATE_FUNCTION: {
// Create Function.
Map<int, Ref<VisualScriptNode>> nodes;
@@ -4135,6 +4164,12 @@ void VisualScriptEditor::_menu_option(int p_what) {
case REFRESH_GRAPH: {
_update_graph();
} break;
+ case EDIT_CLEAR_COPY_BUFFER: {
+ clipboard->nodes.clear();
+ clipboard->nodes_positions.clear();
+ clipboard->data_connections.clear();
+ clipboard->sequence_connections.clear();
+ } break;
}
}
@@ -4322,9 +4357,6 @@ VisualScriptEditor::VisualScriptEditor() {
if (!clipboard) {
clipboard = memnew(Clipboard);
}
- updating_graph = false;
- saved_pos_dirty = false;
- saved_position = Vector2(0, 0);
edit_menu = memnew(MenuButton);
edit_menu->set_shortcut_context(this);
@@ -4556,6 +4588,18 @@ VisualScriptEditor::VisualScriptEditor() {
new_virtual_method_select = memnew(VisualScriptPropertySelector);
add_child(new_virtual_method_select);
new_virtual_method_select->connect("selected", callable_mp(this, &VisualScriptEditor::_selected_new_virtual_method));
+
+ popup_menu = memnew(PopupMenu);
+ add_child(popup_menu);
+ popup_menu->add_item(TTR("Add Node"), EDIT_ADD_NODE);
+ popup_menu->add_separator();
+ popup_menu->add_item(TTR("Cut"), EDIT_CUT_NODES);
+ popup_menu->add_item(TTR("Copy"), EDIT_COPY_NODES);
+ popup_menu->add_item(TTR("Paste"), EDIT_PASTE_NODES);
+ popup_menu->add_item(TTR("Delete"), EDIT_DELETE_NODES);
+ popup_menu->add_item(TTR("Duplicate"), EDIT_DUPLICATE_NODES);
+ popup_menu->add_item(TTR("Clear Copy Buffer"), EDIT_CLEAR_COPY_BUFFER);
+ popup_menu->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option));
}
VisualScriptEditor::~VisualScriptEditor() {
diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h
index b232b05391..90e4fb9d56 100644
--- a/modules/visual_script/editor/visual_script_editor.h
+++ b/modules/visual_script/editor/visual_script_editor.h
@@ -54,13 +54,18 @@ class VisualScriptEditor : public ScriptEditorBase {
};
enum {
- EDIT_DELETE_NODES,
- EDIT_TOGGLE_BREAKPOINT,
- EDIT_FIND_NODE_TYPE,
- EDIT_COPY_NODES,
+ EDIT_ADD_NODE,
+ EDIT_SEPARATOR, // popup menu separator - ignored
EDIT_CUT_NODES,
+ EDIT_COPY_NODES,
EDIT_PASTE_NODES,
+ EDIT_DELETE_NODES,
+ EDIT_DUPLICATE_NODES,
+ EDIT_CLEAR_COPY_BUFFER,
+
EDIT_CREATE_FUNCTION,
+ EDIT_TOGGLE_BREAKPOINT,
+ EDIT_FIND_NODE_TYPE,
REFRESH_GRAPH,
};
@@ -123,7 +128,7 @@ class VisualScriptEditor : public ScriptEditorBase {
Label *select_func_text;
- bool updating_graph;
+ bool updating_graph = false;
void _show_hint(const String &p_hint);
void _hide_timer();
@@ -162,7 +167,8 @@ class VisualScriptEditor : public ScriptEditorBase {
static Clipboard *clipboard;
- PopupMenu *member_popup;
+ PopupMenu *popup_menu = nullptr;
+ PopupMenu *member_popup = nullptr;
MemberType member_type;
String member_name;
@@ -172,8 +178,7 @@ class VisualScriptEditor : public ScriptEditorBase {
Vector2 port_action_pos;
int port_action_new_node;
- bool saved_pos_dirty;
- Vector2 saved_position;
+ bool saved_pos_dirty = false;
Vector2 mouse_up_position;
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index b39f984a80..2abbd19e12 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -176,7 +176,7 @@ PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const
}
String VisualScriptExpression::get_caption() const {
- return "Expression";
+ return TTR("Expression");
}
String VisualScriptExpression::get_text() const {
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index f8b03f2eea..fd1861abc4 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -70,7 +70,7 @@ PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const {
}
String VisualScriptReturn::get_caption() const {
- return "Return";
+ return TTR("Return");
}
String VisualScriptReturn::get_text() const {
@@ -201,11 +201,11 @@ PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const
}
String VisualScriptCondition::get_caption() const {
- return "Condition";
+ return TTR("Condition");
}
String VisualScriptCondition::get_text() const {
- return "if (cond) is: ";
+ return TTR("if (cond) is:");
}
void VisualScriptCondition::_bind_methods() {
@@ -281,11 +281,11 @@ PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const {
}
String VisualScriptWhile::get_caption() const {
- return "While";
+ return TTR("While");
}
String VisualScriptWhile::get_text() const {
- return "while (cond): ";
+ return TTR("while (cond):");
}
void VisualScriptWhile::_bind_methods() {
@@ -364,11 +364,11 @@ PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const {
}
String VisualScriptIterator::get_caption() const {
- return "Iterator";
+ return TTR("Iterator");
}
String VisualScriptIterator::get_text() const {
- return "for (elem) in (input): ";
+ return TTR("for (elem) in (input):");
}
void VisualScriptIterator::_bind_methods() {
@@ -478,11 +478,11 @@ PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSequence::get_caption() const {
- return "Sequence";
+ return TTR("Sequence");
}
String VisualScriptSequence::get_text() const {
- return "in order: ";
+ return TTR("in order:");
}
void VisualScriptSequence::set_steps(int p_steps) {
@@ -587,11 +587,11 @@ PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSwitch::get_caption() const {
- return "Switch";
+ return TTR("Switch");
}
String VisualScriptSwitch::get_text() const {
- return "'input' is:";
+ return TTR("'input' is:");
}
class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance {
@@ -720,14 +720,14 @@ PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const {
}
String VisualScriptTypeCast::get_caption() const {
- return "Type Cast";
+ return TTR("Type Cast");
}
String VisualScriptTypeCast::get_text() const {
if (!script.is_empty()) {
- return "Is " + script.get_file() + "?";
+ return vformat(TTR("Is %s?"), script.get_file());
} else {
- return "Is " + base_type + "?";
+ return vformat(TTR("Is %s?"), base_type);
}
}
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 056e1eb6a3..cc18d48dd8 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -261,13 +261,13 @@ String VisualScriptFunctionCall::get_text() const {
String text;
if (call_mode == CALL_MODE_BASIC_TYPE) {
- text = String("On ") + Variant::get_type_name(basic_type);
+ text = vformat(TTR("On %s"), Variant::get_type_name(basic_type));
} else if (call_mode == CALL_MODE_INSTANCE) {
- text = String("On ") + base_type;
+ text = vformat(TTR("On %s"), base_type);
} else if (call_mode == CALL_MODE_NODE_PATH) {
text = "[" + String(base_path.simplified()) + "]";
} else if (call_mode == CALL_MODE_SELF) {
- text = "On Self";
+ text = TTR("On Self");
} else if (call_mode == CALL_MODE_SINGLETON) {
text = String(singleton) + ":" + String(function) + "()";
}
@@ -1033,15 +1033,25 @@ PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) cons
String VisualScriptPropertySet::get_caption() const {
static const char *opname[ASSIGN_OP_MAX] = {
- "Set", "Add", "Subtract", "Multiply", "Divide", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor"
+ TTRC("Set %s"),
+ TTRC("Add %s"),
+ TTRC("Subtract %s"),
+ TTRC("Multiply %s"),
+ TTRC("Divide %s"),
+ TTRC("Mod %s"),
+ TTRC("ShiftLeft %s"),
+ TTRC("ShiftRight %s"),
+ TTRC("BitAnd %s"),
+ TTRC("BitOr %s"),
+ TTRC("BitXor %s")
};
- String prop = String(opname[assign_op]) + " " + property;
+ String prop = property;
if (index != StringName()) {
prop += "." + String(index);
}
- return prop;
+ return vformat(TTRGET(opname[assign_op]), prop);
}
String VisualScriptPropertySet::get_text() const {
@@ -1049,13 +1059,13 @@ String VisualScriptPropertySet::get_text() const {
return "";
}
if (call_mode == CALL_MODE_BASIC_TYPE) {
- return String("On ") + Variant::get_type_name(basic_type);
+ return vformat(TTR("On %s"), Variant::get_type_name(basic_type));
} else if (call_mode == CALL_MODE_INSTANCE) {
- return String("On ") + base_type;
+ return vformat(TTR("On %s"), base_type);
} else if (call_mode == CALL_MODE_NODE_PATH) {
return " [" + String(base_path.simplified()) + "]";
} else {
- return "On Self";
+ return TTR("On Self");
}
}
@@ -1761,23 +1771,23 @@ PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptPropertyGet::get_caption() const {
- String prop = String("Get ") + property;
+ String prop = property;
if (index != StringName()) {
prop += "." + String(index);
}
- return prop;
+ return vformat(TTR("Get %s"), prop);
}
String VisualScriptPropertyGet::get_text() const {
if (call_mode == CALL_MODE_BASIC_TYPE) {
- return String("On ") + Variant::get_type_name(basic_type);
+ return vformat(TTR("On %s"), Variant::get_type_name(basic_type));
} else if (call_mode == CALL_MODE_INSTANCE) {
- return String("On ") + base_type;
+ return vformat(TTR("On %s"), base_type);
} else if (call_mode == CALL_MODE_NODE_PATH) {
return " [" + String(base_path.simplified()) + "]";
} else {
- return "On Self";
+ return TTR("On Self");
}
}
@@ -2293,7 +2303,7 @@ PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const
}
String VisualScriptEmitSignal::get_caption() const {
- return "Emit " + String(name);
+ return vformat(TTR("Emit %s"), name);
}
void VisualScriptEmitSignal::set_signal(const StringName &p_type) {
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index fccdab1a64..f3594e5164 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -204,7 +204,7 @@ PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
}
String VisualScriptFunction::get_caption() const {
- return "Function";
+ return TTR("Function");
}
String VisualScriptFunction::get_text() const {
@@ -767,7 +767,7 @@ PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) con
}
String VisualScriptComposeArray::get_caption() const {
- return "Compose Array";
+ return TTR("Compose Array");
}
String VisualScriptComposeArray::get_text() const {
@@ -1186,11 +1186,11 @@ PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSelect::get_caption() const {
- return "Select";
+ return TTR("Select");
}
String VisualScriptSelect::get_text() const {
- return "a if cond, else b";
+ return TTR("a if cond, else b");
}
void VisualScriptSelect::set_typed(Variant::Type p_op) {
@@ -1284,7 +1284,7 @@ PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptVariableGet::get_caption() const {
- return "Get " + variable;
+ return vformat(TTR("Get %s"), variable);
}
void VisualScriptVariableGet::set_variable(StringName p_variable) {
@@ -1394,7 +1394,7 @@ PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptVariableSet::get_caption() const {
- return "Set " + variable;
+ return vformat(TTR("Set %s"), variable);
}
void VisualScriptVariableSet::set_variable(StringName p_variable) {
@@ -1501,7 +1501,7 @@ PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const {
}
String VisualScriptConstant::get_caption() const {
- return "Constant";
+ return TTR("Constant");
}
void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
@@ -1628,7 +1628,7 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const {
}
String VisualScriptPreload::get_caption() const {
- return "Preload";
+ return TTR("Preload");
}
void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) {
@@ -1708,7 +1708,7 @@ PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const {
}
String VisualScriptIndexGet::get_caption() const {
- return "Get Index";
+ return TTR("Get Index");
}
class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance {
@@ -1775,7 +1775,7 @@ PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const {
}
String VisualScriptIndexSet::get_caption() const {
- return "Set Index";
+ return TTR("Set Index");
}
class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance {
@@ -1839,7 +1839,7 @@ PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) c
}
String VisualScriptGlobalConstant::get_caption() const {
- return "Global Constant";
+ return TTR("Global Constant");
}
void VisualScriptGlobalConstant::set_global_constant(int p_which) {
@@ -1925,7 +1925,7 @@ PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) co
}
String VisualScriptClassConstant::get_caption() const {
- return "Class Constant";
+ return TTR("Class Constant");
}
void VisualScriptClassConstant::set_class_constant(const StringName &p_which) {
@@ -2050,7 +2050,7 @@ PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx
}
String VisualScriptBasicTypeConstant::get_caption() const {
- return "Basic Constant";
+ return TTR("Basic Constant");
}
String VisualScriptBasicTypeConstant::get_text() const {
@@ -2215,7 +2215,7 @@ PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) con
}
String VisualScriptMathConstant::get_caption() const {
- return "Math Constant";
+ return TTR("Math Constant");
}
void VisualScriptMathConstant::set_math_constant(MathConstant p_which) {
@@ -2307,7 +2307,7 @@ PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx)
}
String VisualScriptEngineSingleton::get_caption() const {
- return "Get Engine Singleton";
+ return TTR("Get Engine Singleton");
}
void VisualScriptEngineSingleton::set_singleton(const String &p_string) {
@@ -2417,7 +2417,7 @@ PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const
}
String VisualScriptSceneNode::get_caption() const {
- return "Get Scene Node";
+ return TTR("Get Scene Node");
}
void VisualScriptSceneNode::set_node_path(const NodePath &p_path) {
@@ -2608,7 +2608,7 @@ PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const
}
String VisualScriptSceneTree::get_caption() const {
- return "Get Scene Tree";
+ return TTR("Get Scene Tree");
}
class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance {
@@ -2695,7 +2695,7 @@ PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) con
}
String VisualScriptResourcePath::get_caption() const {
- return "Resource Path";
+ return TTR("Resource Path");
}
void VisualScriptResourcePath::set_resource_path(const String &p_path) {
@@ -2777,7 +2777,7 @@ PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSelf::get_caption() const {
- return "Get Self";
+ return TTR("Get Self");
}
class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance {
@@ -2947,7 +2947,7 @@ String VisualScriptCustomNode::get_caption() const {
if (GDVIRTUAL_CALL(_get_caption, ret)) {
return ret;
}
- return "CustomNode";
+ return TTR("CustomNode");
}
String VisualScriptCustomNode::get_text() const {
@@ -3141,7 +3141,7 @@ PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSubCall::get_caption() const {
- return "SubCall";
+ return TTR("SubCall");
}
String VisualScriptSubCall::get_text() const {
@@ -3352,7 +3352,7 @@ PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) cons
}
String VisualScriptConstructor::get_caption() const {
- return "Construct " + Variant::get_type_name(type);
+ return vformat(TTR("Construct %s"), Variant::get_type_name(type));
}
String VisualScriptConstructor::get_category() const {
@@ -3469,7 +3469,7 @@ PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const {
}
String VisualScriptLocalVar::get_caption() const {
- return "Get Local Var";
+ return TTR("Get Local Var");
}
String VisualScriptLocalVar::get_category() const {
@@ -3572,7 +3572,7 @@ PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptLocalVarSet::get_caption() const {
- return "Set Local Var";
+ return TTR("Set Local Var");
}
String VisualScriptLocalVarSet::get_text() const {
@@ -3696,7 +3696,7 @@ PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) cons
}
String VisualScriptInputAction::get_caption() const {
- return "Action " + name;
+ return vformat(TTR("Action %s"), name);
}
String VisualScriptInputAction::get_category() const {
@@ -3850,7 +3850,7 @@ PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) cons
}
String VisualScriptDeconstruct::get_caption() const {
- return "Deconstruct " + Variant::get_type_name(type);
+ return vformat(TTR("Deconstruct %s"), Variant::get_type_name(type));
}
String VisualScriptDeconstruct::get_category() const {
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index d4f3fdd082..fbd5ad35ab 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -68,7 +68,7 @@ PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const {
}
String VisualScriptYield::get_caption() const {
- return yield_mode == YIELD_RETURN ? "Yield" : "Wait";
+ return yield_mode == YIELD_RETURN ? TTR("Yield") : TTR("Wait");
}
String VisualScriptYield::get_text() const {
@@ -77,13 +77,13 @@ String VisualScriptYield::get_text() const {
return "";
break;
case YIELD_FRAME:
- return "Next Frame";
+ return TTR("Next Frame");
break;
case YIELD_PHYSICS_FRAME:
- return "Next Physics Frame";
+ return TTR("Next Physics Frame");
break;
case YIELD_WAIT:
- return rtos(wait_time) + " sec(s)";
+ return vformat(TTR("%s sec(s)"), rtos(wait_time));
break;
}
@@ -336,12 +336,12 @@ PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) cons
String VisualScriptYieldSignal::get_caption() const {
static const char *cname[3] = {
- "WaitSignal",
- "WaitNodeSignal",
- "WaitInstanceSigna;",
+ TTRC("WaitSignal"),
+ TTRC("WaitNodeSignal"),
+ TTRC("WaitInstanceSignal"),
};
- return cname[call_mode];
+ return TTRGET(cname[call_mode]);
}
String VisualScriptYieldSignal::get_text() const {
diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp
index b7249e4243..b3f0140b80 100644
--- a/modules/websocket/websocket_server.cpp
+++ b/modules/websocket/websocket_server.cpp
@@ -67,7 +67,7 @@ void WebSocketServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout);
ClassDB::bind_method(D_METHOD("set_handshake_timeout", "timeout"), &WebSocketServer::set_handshake_timeout);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout");
ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason")));
ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close")));
diff --git a/modules/webxr/webxr_interface.h b/modules/webxr/webxr_interface.h
index 291d53044f..801643bfa6 100644
--- a/modules/webxr/webxr_interface.h
+++ b/modules/webxr/webxr_interface.h
@@ -35,8 +35,6 @@
#include "servers/xr/xr_positional_tracker.h"
/**
- @author David Snopek <david.snopek@snopekgames.com>
-
The WebXR interface is a VR/AR interface that can be used on the web.
*/
diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h
index 3eec451d50..8eddfbe484 100644
--- a/modules/webxr/webxr_interface_js.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -36,8 +36,6 @@
#include "webxr_interface.h"
/**
- @author David Snopek <david.snopek@snopekgames.com>
-
The WebXR interface is a VR/AR interface that can be used on the web.
*/
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index cbecde787f..aa44183329 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -2666,6 +2666,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
debug_password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
debug_user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
}
+ if (debug_keystore.is_relative_path()) {
+ debug_keystore = OS::get_singleton()->get_resource_dir().plus_file(debug_keystore).simplify_path();
+ }
+ if (!FileAccess::exists(debug_keystore)) {
+ EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ return ERR_FILE_CANT_OPEN;
+ }
cmdline.push_back("-Pdebug_keystore_file=" + debug_keystore); // argument to specify the debug keystore file.
cmdline.push_back("-Pdebug_keystore_alias=" + debug_user); // argument to specify the debug keystore alias.
@@ -2675,6 +2682,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String release_keystore = p_preset->get("keystore/release");
String release_username = p_preset->get("keystore/release_user");
String release_password = p_preset->get("keystore/release_password");
+ if (release_keystore.is_relative_path()) {
+ release_keystore = OS::get_singleton()->get_resource_dir().plus_file(release_keystore).simplify_path();
+ }
if (!FileAccess::exists(release_keystore)) {
EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
index 9ea787ac86..e5b4f41153 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
@@ -45,8 +45,8 @@ import java.util.List;
/**
* This class includes utility functions for Android permissions related operations.
- * @author Cagdas Caglak <cagdascaglak@gmail.com>
*/
+
public final class PermissionsUtil {
private static final String TAG = PermissionsUtil.class.getSimpleName();
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index 5d960ef80c..f98e0c4c5f 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -230,7 +230,7 @@ void DisplayServerJavaScript::mouse_move_callback(double p_x, double p_y, double
ev->set_relative(Vector2(p_rel_x, p_rel_y));
Input::get_singleton()->set_mouse_position(ev->get_position());
- ev->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ ev->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
Input::get_singleton()->parse_input_event(ev);
}
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 68bd5e8421..747b5beeda 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -3648,7 +3648,7 @@ void DisplayServerX11::process_events() {
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_velocity(Input::get_singleton()->get_last_mouse_velocity());
mm->set_relative(rel);
@@ -3678,7 +3678,7 @@ void DisplayServerX11::process_events() {
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());
+ mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
Input::get_singleton()->parse_input_event(mm);
break;
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index b5fd3664d3..1dcedabb1a 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -31,8 +31,6 @@
#ifndef DISPLAY_SERVER_X11_H
#define DISPLAY_SERVER_X11_H
-#include "drivers/gles3/rasterizer_platforms.h"
-
#ifdef X11_ENABLED
#include "servers/display_server.h"
diff --git a/platform/linuxbsd/gl_manager_x11.h b/platform/linuxbsd/gl_manager_x11.h
index c83b96395b..0bb0a446ab 100644
--- a/platform/linuxbsd/gl_manager_x11.h
+++ b/platform/linuxbsd/gl_manager_x11.h
@@ -33,8 +33,6 @@
#ifdef X11_ENABLED
-#include "drivers/gles3/rasterizer_platforms.h"
-
#ifdef GLES3_ENABLED
#include "core/os/os.h"
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 42797afdfa..edbcfcbfa6 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -28,7 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-//author: Andreas Haas <hondres, liugam3@gmail.com>
#ifndef JOYPAD_LINUX_H
#define JOYPAD_LINUX_H
@@ -100,5 +99,6 @@ private:
Input::JoyAxisValue axis_correct(const input_absinfo *p_abs, int p_value) const;
};
-#endif
+#endif // JOYDEV_ENABLED
+
#endif // JOYPAD_LINUX_H
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index e9cc79f149..27d302a984 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -787,7 +787,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, M
mm->set_tilt(Vector2(p.x, p.y));
}
mm->set_global_position(pos);
- mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * DS_OSX->screen_get_max_scale();
mm->set_relative(relativeMotion);
_get_key_modifier_state([event modifierFlags], mm);
@@ -3575,6 +3575,7 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V
[wd.window_object setDelegate:wd.window_delegate];
[wd.window_object setAcceptsMouseMovedEvents:YES];
[wd.window_object setRestorable:NO];
+ [wd.window_object setColorSpace:[NSColorSpace sRGBColorSpace]];
if ([wd.window_object respondsToSelector:@selector(setTabbingMode:)]) {
[wd.window_object setTabbingMode:NSWindowTabbingModeDisallowed];
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index ab50144303..3a731f2172 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -381,12 +381,22 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
#ifdef OSX_ENABLED
List<String> args;
+ bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-");
+
if (p_preset->get("codesign/timestamp")) {
- args.push_back("--timestamp");
+ if (ad_hoc) {
+ WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+ } else {
+ args.push_back("--timestamp");
+ }
}
if (p_preset->get("codesign/hardened_runtime")) {
- args.push_back("--options");
- args.push_back("runtime");
+ if (ad_hoc) {
+ WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+ } else {
+ args.push_back("--options");
+ args.push_back("runtime");
+ }
}
if (p_path.get_extension() != "dmg") {
@@ -403,7 +413,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
}
args.push_back("-s");
- if (p_preset->get("codesign/identity") == "") {
+ if (ad_hoc) {
args.push_back("-");
} else {
args.push_back(p_preset->get("codesign/identity"));
@@ -1166,10 +1176,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
String err;
bool valid = false;
- // Look for export templates (first official, and if defined custom templates).
-
- bool dvalid = exists_export_template("osx.zip", &err);
- bool rvalid = dvalid; // Both in the same ZIP.
+ // Look for export templates (custom templates).
+ bool dvalid = false;
+ bool rvalid = false;
if (p_preset->get("custom_template/debug") != "") {
dvalid = FileAccess::exists(p_preset->get("custom_template/debug"));
@@ -1184,6 +1193,12 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
}
}
+ // Look for export templates (official templates, check only is custom templates are not set).
+ if (!dvalid || !rvalid) {
+ dvalid = exists_export_template("osx.zip", &err);
+ rvalid = dvalid; // Both in the same ZIP.
+ }
+
valid = dvalid || rvalid;
r_missing_templates = !valid;
@@ -1194,16 +1209,26 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
valid = false;
}
+#ifdef OSX_ENABLED
bool sign_enabled = p_preset->get("codesign/enable");
bool noto_enabled = p_preset->get("notarization/enable");
+ bool ad_hoc = ((p_preset->get("codesign/identity") == "") || (p_preset->get("codesign/identity") == "-"));
+
if (noto_enabled) {
+ if (ad_hoc) {
+ err += TTR("Notarization: Notarization with the ad-hoc signature is not supported.") + "\n";
+ valid = false;
+ }
if (!sign_enabled) {
- err += TTR("Notarization: code signing required.") + "\n";
+ err += TTR("Notarization: Code signing is required for notarization.") + "\n";
+ valid = false;
+ }
+ if (!(bool)p_preset->get("codesign/hardened_runtime")) {
+ err += TTR("Notarization: Hardened runtime is required for notarization.") + "\n";
valid = false;
}
- bool hr_enabled = p_preset->get("codesign/hardened_runtime");
- if (!hr_enabled) {
- err += TTR("Notarization: hardened runtime required.") + "\n";
+ if (!(bool)p_preset->get("codesign/timestamp")) {
+ err += TTR("Notarization: Timestamping is required for notarization.") + "\n";
valid = false;
}
if (p_preset->get("notarization/apple_id_name") == "") {
@@ -1214,7 +1239,22 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
err += TTR("Notarization: Apple ID password not specified.") + "\n";
valid = false;
}
+ } else {
+ err += TTR("Notarization is disabled. Exported project will be blocked by Gatekeeper, if it's downloaded from an unknown source.") + "\n";
+ if (!sign_enabled) {
+ err += TTR("Code signing is disabled. Exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n";
+ } else {
+ if ((bool)p_preset->get("codesign/hardened_runtime") && ad_hoc) {
+ err += TTR("Hardened Runtime is not compatible with ad-hoc signature, and will be disabled!") + "\n";
+ }
+ if ((bool)p_preset->get("codesign/timestamp") && ad_hoc) {
+ err += TTR("Timestamping is not compatible with ad-hoc signature, and will be disabled!") + "\n";
+ }
+ }
}
+#else
+ err += TTR("macOS code signing and Notarization is not supported on the host OS. Exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n";
+#endif
if (!err.is_empty()) {
r_error = err;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 7d07b0076b..821036de9c 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -82,9 +82,9 @@
@implementation GodotApplicationDelegate
- (void)forceUnbundledWindowActivationHackStep1 {
- // Step1: Switch focus to macOS Dock.
+ // Step 1: Switch focus to macOS SystemUIServer process.
// Required to perform step 2, TransformProcessType will fail if app is already the in focus.
- for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) {
+ for (NSRunningApplication *app in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.systemuiserver"]) {
[app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
break;
}
@@ -107,8 +107,8 @@
- (void)applicationDidFinishLaunching:(NSNotification *)notice {
NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
- if (nsappname == nil) {
- // If executable is not a bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored).
+ if (nsappname == nil || isatty(STDOUT_FILENO) || isatty(STDIN_FILENO) || isatty(STDERR_FILENO)) {
+ // If the executable is started from terminal or is not bundled, macOS WindowServer won't register and activate app window correctly (menu and title bar are grayed out and input ignored).
[self performSelector:@selector(forceUnbundledWindowActivationHackStep1) withObject:nil afterDelay:0.02];
}
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index ca2b68371c..091bed36ea 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2079,7 +2079,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_position(c);
mm->set_global_position(c);
Input::get_singleton()->set_mouse_position(c);
- mm->set_speed(Vector2(0, 0));
+ mm->set_velocity(Vector2(0, 0));
if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
@@ -2184,7 +2184,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
Input::get_singleton()->set_mouse_position(mm->get_position());
- mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
old_x = mm->get_position().x;
@@ -2326,7 +2326,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
Input::get_singleton()->set_mouse_position(mm->get_position());
- mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
old_x = mm->get_position().x;
@@ -2427,7 +2427,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
Input::get_singleton()->set_mouse_position(mm->get_position());
- mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+ mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
if (old_invalid) {
old_x = mm->get_position().x;
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 9bc3226851..2923b287be 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -164,15 +164,15 @@ void CollisionPolygon2D::_notification(int p_what) {
dcol.a = 1.0;
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, dcol, 3);
- Vector<Vector2> pts;
real_t tsize = 8;
- pts.push_back(line_to + (Vector2(0, tsize)));
- pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
- pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(dcol);
- }
+
+ Vector<Vector2> pts = {
+ line_to + Vector2(0, tsize),
+ line_to + Vector2(Math_SQRT12 * tsize, 0),
+ line_to + Vector2(-Math_SQRT12 * tsize, 0)
+ };
+
+ Vector<Color> cols{ dcol, dcol, dcol };
draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
}
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index 18426c088d..a0520ca28f 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -121,15 +121,15 @@ void CollisionShape2D::_notification(int p_what) {
}
Vector2 line_to(0, 20);
draw_line(Vector2(), line_to, draw_col, 2);
- Vector<Vector2> pts;
real_t tsize = 8;
- pts.push_back(line_to + (Vector2(0, tsize)));
- pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
- pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+
+ Vector<Vector2> pts{
+ line_to + Vector2(0, tsize),
+ line_to + Vector2(Math_SQRT12 * tsize, 0),
+ line_to + Vector2(-Math_SQRT12 * tsize, 0)
+ };
+
+ Vector<Color> cols{ draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index f62e7f24e3..4673a99082 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -152,11 +152,14 @@ void CPUParticles2D::_update_mesh_texture() {
} else {
tex_size = Size2(1, 1);
}
- Vector<Vector2> vertices;
- vertices.push_back(-tex_size * 0.5);
- vertices.push_back(-tex_size * 0.5 + Vector2(tex_size.x, 0));
- vertices.push_back(-tex_size * 0.5 + tex_size);
- vertices.push_back(-tex_size * 0.5 + Vector2(0, tex_size.y));
+
+ Vector<Vector2> vertices = {
+ -tex_size * 0.5,
+ -tex_size * 0.5 + Vector2(tex_size.x, 0),
+ -tex_size * 0.5 + tex_size,
+ -tex_size * 0.5 + Vector2(0, tex_size.y)
+ };
+
Vector<Vector2> uvs;
AtlasTexture *atlas_texure = Object::cast_to<AtlasTexture>(*texture);
if (atlas_texure && atlas_texure->get_atlas().is_valid()) {
@@ -172,18 +175,15 @@ void CPUParticles2D::_update_mesh_texture() {
uvs.push_back(Vector2(1, 1));
uvs.push_back(Vector2(0, 1));
}
- Vector<Color> colors;
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- Vector<int> indices;
- indices.push_back(0);
- indices.push_back(1);
- indices.push_back(2);
- indices.push_back(2);
- indices.push_back(3);
- indices.push_back(0);
+
+ Vector<Color> colors = {
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1),
+ Color(1, 1, 1, 1)
+ };
+
+ Vector<int> indices = { 0, 1, 2, 2, 3, 0 };
Array arr;
arr.resize(RS::ARRAY_MAX);
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index 8c8f794298..b6d1e5c934 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -427,26 +427,23 @@ void GPUParticles2D::_notification(int p_what) {
} else {
RS::get_singleton()->mesh_clear(mesh);
- Vector<Vector2> points;
- points.resize(4);
- points.write[0] = Vector2(-size.x / 2.0, -size.y / 2.0);
- points.write[1] = Vector2(size.x / 2.0, -size.y / 2.0);
- points.write[2] = Vector2(size.x / 2.0, size.y / 2.0);
- points.write[3] = Vector2(-size.x / 2.0, size.y / 2.0);
- Vector<Vector2> uvs;
- uvs.resize(4);
- uvs.write[0] = Vector2(0, 0);
- uvs.write[1] = Vector2(1, 0);
- uvs.write[2] = Vector2(1, 1);
- uvs.write[3] = Vector2(0, 1);
- Vector<int> indices;
- indices.resize(6);
- indices.write[0] = 0;
- indices.write[1] = 1;
- indices.write[2] = 2;
- indices.write[3] = 0;
- indices.write[4] = 2;
- indices.write[5] = 3;
+
+ Vector<Vector2> points = {
+ Vector2(-size.x / 2.0, -size.y / 2.0),
+ Vector2(size.x / 2.0, -size.y / 2.0),
+ Vector2(size.x / 2.0, size.y / 2.0),
+ Vector2(-size.x / 2.0, size.y / 2.0)
+ };
+
+ Vector<Vector2> uvs = {
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ Vector2(0, 1)
+ };
+
+ Vector<int> indices = { 0, 1, 2, 0, 2, 3 };
+
Array arr;
arr.resize(RS::ARRAY_MAX);
arr[RS::ARRAY_VERTEX] = points;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 5451d95be9..1f4dec6864 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -662,7 +662,7 @@ void Polygon2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR2_ARRAY, "uv"), "set_uv", "get_uv");
ADD_PROPERTY(PropertyInfo(Variant::PACKED_COLOR_ARRAY, "vertex_colors"), "set_vertex_colors", "get_vertex_colors");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "polygons"), "set_polygons", "get_polygons");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bones", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_bones", "_get_bones");
ADD_PROPERTY(PropertyInfo(Variant::INT, "internal_vertex_count", PROPERTY_HINT_RANGE, "0,1000"), "set_internal_vertex_count", "get_internal_vertex_count");
}
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 28aeff98ca..67aff9c520 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -36,37 +36,41 @@ void Position2D::_draw_cross() {
const real_t extents = get_gizmo_extents();
// Add more points to create a "hard stop" in the color gradient.
- PackedVector2Array points_x;
- points_x.push_back(Point2(+extents, 0));
- points_x.push_back(Point2());
- points_x.push_back(Point2());
- points_x.push_back(Point2(-extents, 0));
-
- PackedVector2Array points_y;
- points_y.push_back(Point2(0, +extents));
- points_y.push_back(Point2());
- points_y.push_back(Point2());
- points_y.push_back(Point2(0, -extents));
+ PackedVector2Array points_x = {
+ Point2(+extents, 0),
+ Point2(),
+ Point2(),
+ Point2(-extents, 0)
+ };
+
+ PackedVector2Array points_y = {
+ Point2(0, +extents),
+ Point2(),
+ Point2(),
+ Point2(0, -extents)
+ };
// Use the axis color which is brighter for the positive axis.
// Use a darkened axis color for the negative axis.
// This makes it possible to see in which direction the Position3D node is rotated
// (which can be important depending on how it's used).
// Axis colors are taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`).
- PackedColorArray colors_x;
const Color color_x = Color(0.96, 0.20, 0.32);
- colors_x.push_back(color_x);
- colors_x.push_back(color_x);
- colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5));
- colors_x.push_back(color_x.lerp(Color(0, 0, 0), 0.5));
+ PackedColorArray colors_x = {
+ color_x,
+ color_x,
+ color_x.lerp(Color(0, 0, 0), 0.5),
+ color_x.lerp(Color(0, 0, 0), 0.5)
+ };
draw_multiline_colors(points_x, colors_x);
- PackedColorArray colors_y;
const Color color_y = Color(0.53, 0.84, 0.01);
- colors_y.push_back(color_y);
- colors_y.push_back(color_y);
- colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5));
- colors_y.push_back(color_y.lerp(Color(0, 0, 0), 0.5));
+ PackedColorArray colors_y = {
+ color_y,
+ color_y,
+ color_y.lerp(Color(0, 0, 0), 0.5),
+ color_y.lerp(Color(0, 0, 0), 0.5)
+ };
draw_multiline_colors(points_y, colors_y);
}
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 33090fbacc..1fdd8b05a6 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -244,15 +244,13 @@ void RayCast2D::_draw_debug_shape() {
xf.rotate(target_position.angle());
xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(arrow_size, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
-
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(draw_col);
- }
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(arrow_size, 0)),
+ xf.xform(Vector2(0, 0.5 * arrow_size)),
+ xf.xform(Vector2(0, -0.5 * arrow_size))
+ };
+
+ Vector<Color> cols = { draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp
index 7fc1992e96..10194861b4 100644
--- a/scene/2d/shape_cast_2d.cpp
+++ b/scene/2d/shape_cast_2d.cpp
@@ -239,14 +239,16 @@ void ShapeCast2D::_notification(int p_what) {
xf.translate(Vector2(target_position.length(), 0));
draw_line(Vector2(), target_position, draw_col, 2);
- Vector<Vector2> pts;
+
float tsize = 8;
- pts.push_back(xf.xform(Vector2(tsize, 0)));
- pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize)));
- pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize)));
- Vector<Color> cols;
- for (int i = 0; i < 3; i++)
- cols.push_back(draw_col);
+
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(tsize, 0)),
+ xf.xform(Vector2(0, Math_SQRT12 * tsize)),
+ xf.xform(Vector2(0, -Math_SQRT12 * tsize))
+ };
+
+ Vector<Color> cols = { draw_col, draw_col, draw_col };
draw_primitive(pts, cols, Vector<Vector2>());
}
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index d2ba6809b3..3bb65d07a0 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -355,7 +355,7 @@ void RayCast3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_shape_thickness", PROPERTY_HINT_RANGE, "1,5"), "set_debug_shape_thickness", "get_debug_shape_thickness");
}
-float RayCast3D::get_debug_shape_thickness() const {
+int RayCast3D::get_debug_shape_thickness() const {
return debug_shape_thickness;
}
@@ -384,7 +384,7 @@ void RayCast3D::_update_debug_shape_vertices() {
}
}
-void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) {
+void RayCast3D::set_debug_shape_thickness(const int p_debug_shape_thickness) {
debug_shape_thickness = p_debug_shape_thickness;
update_gizmos();
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index a580afe8db..a53e2c83fc 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -105,8 +105,8 @@ public:
Ref<StandardMaterial3D> get_debug_material();
- float get_debug_shape_thickness() const;
- void set_debug_shape_thickness(const float p_debug_thickness);
+ int get_debug_shape_thickness() const;
+ void set_debug_shape_thickness(const int p_debug_thickness);
void force_raycast_update();
bool is_colliding() const;
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index 6089c785a2..c645009c72 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -28,10 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
- * @author AndreaCatania
- */
-
#include "skeleton_ik_3d.h"
#ifndef _3D_DISABLED
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 2b4ddce0e2..a37fce9469 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -141,15 +141,6 @@ real_t SpriteBase3D::get_pixel_size() const {
return pixel_size;
}
-void SpriteBase3D::set_opacity(float p_amount) {
- opacity = p_amount;
- _queue_update();
-}
-
-float SpriteBase3D::get_opacity() const {
- return opacity;
-}
-
void SpriteBase3D::set_axis(Vector3::Axis p_axis) {
ERR_FAIL_INDEX(p_axis, 3);
axis = p_axis;
@@ -295,9 +286,6 @@ void SpriteBase3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &SpriteBase3D::set_modulate);
ClassDB::bind_method(D_METHOD("get_modulate"), &SpriteBase3D::get_modulate);
- ClassDB::bind_method(D_METHOD("set_opacity", "opacity"), &SpriteBase3D::set_opacity);
- ClassDB::bind_method(D_METHOD("get_opacity"), &SpriteBase3D::get_opacity);
-
ClassDB::bind_method(D_METHOD("set_pixel_size", "pixel_size"), &SpriteBase3D::set_pixel_size);
ClassDB::bind_method(D_METHOD("get_pixel_size"), &SpriteBase3D::get_pixel_size);
@@ -324,7 +312,6 @@ void SpriteBase3D::_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_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "opacity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_opacity", "get_opacity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pixel_size", PROPERTY_HINT_RANGE, "0.0001,128,0.0001"), "set_pixel_size", "get_pixel_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X-Axis,Y-Axis,Z-Axis"), "set_axis", "get_axis");
ADD_GROUP("Flags", "");
@@ -468,7 +455,6 @@ void Sprite3D::_draw() {
}
Color color = _get_color_accum();
- color.a *= get_opacity();
real_t pixel_size = get_pixel_size();
@@ -837,7 +823,6 @@ void AnimatedSprite3D::_draw() {
}
Color color = _get_color_accum();
- color.a *= get_opacity();
real_t pixel_size = get_pixel_size();
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index 6a61219edf..985103e190 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -69,7 +69,6 @@ private:
bool vflip = false;
Color modulate = Color(1, 1, 1, 1);
- float opacity = 1.0;
Vector3::Axis axis = Vector3::AXIS_Z;
real_t pixel_size = 0.01;
@@ -121,9 +120,6 @@ public:
void set_modulate(const Color &p_color);
Color get_modulate() const;
- void set_opacity(float p_amount);
- float get_opacity() const;
-
void set_pixel_size(real_t p_amount);
real_t get_pixel_size() const;
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index 8e1ef1a4fb..5675cbd944 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -34,13 +34,10 @@
#include "scene/3d/camera_3d.h"
#include "servers/xr/xr_positional_tracker.h"
-/**
- @author Bastiaan Olij <mux213@gmail.com>
-**/
-
/*
XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned
*/
+
class XRCamera3D : public Camera3D {
GDCLASS(XRCamera3D, Camera3D);
@@ -181,6 +178,7 @@ public:
Our camera and controllers will always be child nodes and thus place relative to this origin point.
This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers.
*/
+
class XROrigin3D : public Node3D {
GDCLASS(XROrigin3D, Node3D);
@@ -204,4 +202,4 @@ public:
~XROrigin3D() {}
};
-#endif /* XR_NODES_H */
+#endif // XR_NODES_H
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 2e6a123016..a37c6f5355 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -260,10 +260,8 @@ bool Tween::step(float p_delta) {
}
if (is_bound) {
- Object *bound_instance = ObjectDB::get_instance(bound_node);
- if (bound_instance) {
- Node *bound_node = Object::cast_to<Node>(bound_instance);
- // This can't by anything else than Node, so we can omit checking if casting succeeded.
+ Node *bound_node = get_bound_node();
+ if (bound_node) {
if (!bound_node->is_inside_tree()) {
return true;
}
@@ -320,16 +318,23 @@ bool Tween::step(float p_delta) {
return true;
}
-bool Tween::should_pause() {
+bool Tween::can_process(bool p_tree_paused) const {
if (is_bound && pause_mode == TWEEN_PAUSE_BOUND) {
- Object *bound_instance = ObjectDB::get_instance(bound_node);
- if (bound_instance) {
- Node *bound_node = Object::cast_to<Node>(bound_instance);
- return !bound_node->can_process();
+ Node *bound_node = get_bound_node();
+ if (bound_node) {
+ return bound_node->can_process();
}
}
- return pause_mode != TWEEN_PAUSE_PROCESS;
+ return !p_tree_paused || pause_mode == TWEEN_PAUSE_PROCESS;
+}
+
+Node *Tween::get_bound_node() const {
+ if (is_bound) {
+ return Object::cast_to<Node>(ObjectDB::get_instance(bound_node));
+ } else {
+ return nullptr;
+ }
}
real_t Tween::run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t p_time, real_t p_initial, real_t p_delta, real_t p_duration) {
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index 7ecdb64f0d..5b0745b2b3 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -97,7 +97,7 @@ public:
private:
TweenProcessMode process_mode = TweenProcessMode::TWEEN_PROCESS_IDLE;
- TweenPauseMode pause_mode = TweenPauseMode::TWEEN_PAUSE_STOP;
+ TweenPauseMode pause_mode = TweenPauseMode::TWEEN_PAUSE_BOUND;
TransitionType default_transition = TransitionType::TRANS_LINEAR;
EaseType default_ease = EaseType::EASE_IN_OUT;
ObjectID bound_node;
@@ -164,7 +164,8 @@ public:
Variant calculate_delta_value(Variant p_intial_val, Variant p_final_val);
bool step(float p_delta);
- bool should_pause();
+ bool can_process(bool p_tree_paused) const;
+ Node *get_bound_node() const;
Tween() {}
};
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index dc030d6f3d..046b9c18c7 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -499,7 +499,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -507,7 +507,7 @@ bool Button::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
_shape();
update();
@@ -539,7 +539,7 @@ bool Button::_get(const StringName &p_name, Variant &r_ret) const {
void Button::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h
index 735c7aedfe..fcdb2ce08c 100644
--- a/scene/gui/check_box.h
+++ b/scene/gui/check_box.h
@@ -32,9 +32,7 @@
#define CHECK_BOX_H
#include "scene/gui/button.h"
-/**
-@author Mariano Suligoy <marianognu.esyrpg@gmail.com>
-*/
+
class CheckBox : public Button {
GDCLASS(CheckBox, Button);
@@ -50,4 +48,4 @@ public:
~CheckBox();
};
-#endif
+#endif // CHECK_BOX_H
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index 5ba81a1027..9a72d04db2 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -32,9 +32,7 @@
#define CHECK_BUTTON_H
#include "scene/gui/button.h"
-/**
-@author Juan Linietsky <reduzio@gmail.com>
-*/
+
class CheckButton : public Button {
GDCLASS(CheckButton, Button);
@@ -48,4 +46,4 @@ public:
~CheckButton();
};
-#endif
+#endif // CHECK_BUTTON_H
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 378bfb69dc..79b73f7cc3 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -35,6 +35,7 @@
#include "core/os/keyboard.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
+#include "scene/gui/view_panner.h"
constexpr int MINIMAP_OFFSET = 12;
constexpr int MINIMAP_PADDING = 5;
@@ -1069,13 +1070,9 @@ void GraphEdit::set_selected(Node *p_child) {
void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
+ panner->gui_input(p_ev);
Ref<InputEventMouseMotion> mm = p_ev;
- if (mm.is_valid() && ((mm->get_button_mask() & MouseButton::MASK_MIDDLE) != MouseButton::NONE || ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE && Input::get_singleton()->is_key_pressed(Key::SPACE)))) {
- Vector2i relative = Input::get_singleton()->warp_mouse_motion(mm, get_global_rect());
- h_scroll->set_value(h_scroll->get_value() - relative.x);
- v_scroll->set_value(v_scroll->get_value() - relative.y);
- }
if (mm.is_valid() && dragging) {
if (!moving_selection) {
@@ -1327,22 +1324,6 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
top_layer->update();
minimap->update();
}
-
- int scroll_direction = (b->get_button_index() == MouseButton::WHEEL_DOWN) - (b->get_button_index() == MouseButton::WHEEL_UP);
- if (scroll_direction != 0) {
- if (b->is_ctrl_pressed()) {
- if (b->is_shift_pressed()) {
- // Horizontal scrolling.
- h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * b->get_factor() / 8) * scroll_direction);
- } else {
- // Vertical scrolling.
- v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * b->get_factor() / 8) * scroll_direction);
- }
- } else {
- // Zooming.
- set_zoom_custom(scroll_direction < 0 ? zoom * zoom_step : zoom / zoom_step, b->get_position());
- }
- }
}
if (p_ev->is_pressed()) {
@@ -1373,6 +1354,23 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
}
}
+void GraphEdit::_scroll_callback(Vector2 p_scroll_vec) {
+ if (p_scroll_vec.x != 0) {
+ h_scroll->set_value(h_scroll->get_value() + (h_scroll->get_page() * Math::abs(p_scroll_vec.x) / 8) * SIGN(p_scroll_vec.x));
+ } else {
+ v_scroll->set_value(v_scroll->get_value() + (v_scroll->get_page() * Math::abs(p_scroll_vec.y) / 8) * SIGN(p_scroll_vec.y));
+ }
+}
+
+void GraphEdit::_pan_callback(Vector2 p_scroll_vec) {
+ h_scroll->set_value(h_scroll->get_value() - p_scroll_vec.x);
+ v_scroll->set_value(v_scroll->get_value() - p_scroll_vec.y);
+}
+
+void GraphEdit::_zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin) {
+ set_zoom_custom(p_scroll_vec.y < 0 ? zoom * zoom_step : zoom / zoom_step, p_origin);
+}
+
void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) {
for (Connection &E : connections) {
if (E.from == p_from && E.from_port == p_from_port && E.to == p_to && E.to_port == p_to_port) {
@@ -1406,6 +1404,15 @@ void GraphEdit::force_connection_drag_end() {
emit_signal(SNAME("connection_drag_ended"));
}
+void GraphEdit::set_panning_scheme(PanningScheme p_scheme) {
+ panning_scheme = p_scheme;
+ panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme);
+}
+
+GraphEdit::PanningScheme GraphEdit::get_panning_scheme() const {
+ return panning_scheme;
+}
+
void GraphEdit::set_zoom(float p_zoom) {
set_zoom_custom(p_zoom, get_size() / 2);
}
@@ -2190,6 +2197,9 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type);
ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line);
+ ClassDB::bind_method(D_METHOD("set_panning_scheme", "scheme"), &GraphEdit::set_panning_scheme);
+ ClassDB::bind_method(D_METHOD("get_panning_scheme"), &GraphEdit::get_panning_scheme);
+
ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom);
@@ -2244,6 +2254,7 @@ void GraphEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_snap"), "set_use_snap", "is_using_snap");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "panning_scheme", PROPERTY_HINT_ENUM, "Scroll Zooms,Scroll Pans"), "set_panning_scheme", "get_panning_scheme");
ADD_GROUP("Connection Lines", "connection_lines");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "connection_lines_thickness"), "set_connection_lines_thickness", "get_connection_lines_thickness");
@@ -2277,6 +2288,9 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("scroll_offset_changed", PropertyInfo(Variant::VECTOR2, "ofs")));
ADD_SIGNAL(MethodInfo("connection_drag_started", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::STRING, "slot"), PropertyInfo(Variant::BOOL, "is_output")));
ADD_SIGNAL(MethodInfo("connection_drag_ended"));
+
+ BIND_ENUM_CONSTANT(SCROLL_ZOOMS);
+ BIND_ENUM_CONSTANT(SCROLL_PANS);
}
GraphEdit::GraphEdit() {
@@ -2289,6 +2303,10 @@ GraphEdit::GraphEdit() {
// Allow zooming 4 times from the default zoom level.
zoom_max = (1 * Math::pow(zoom_step, 4));
+ panner.instantiate();
+ panner->set_callbacks(callable_mp(this, &GraphEdit::_scroll_callback), callable_mp(this, &GraphEdit::_pan_callback), callable_mp(this, &GraphEdit::_zoom_callback));
+ panner->set_disable_rmb(true);
+
top_layer = memnew(GraphEditFilter(this));
add_child(top_layer, false, INTERNAL_MODE_BACK);
top_layer->set_mouse_filter(MOUSE_FILTER_PASS);
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 145e0dcc59..4e998d30a7 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -41,6 +41,7 @@
#include "scene/gui/texture_rect.h"
class GraphEdit;
+class ViewPanner;
class GraphEditFilter : public Control {
GDCLASS(GraphEditFilter, Control);
@@ -103,6 +104,12 @@ public:
float activity = 0.0;
};
+ // Should be in sync with ControlScheme in ViewPanner.
+ enum PanningScheme {
+ SCROLL_ZOOMS,
+ SCROLL_PANS,
+ };
+
private:
Label *zoom_label;
Button *zoom_minus;
@@ -122,6 +129,11 @@ private:
float port_grab_distance_horizontal = 0.0;
float port_grab_distance_vertical;
+ Ref<ViewPanner> panner;
+ void _scroll_callback(Vector2 p_scroll_vec);
+ void _pan_callback(Vector2 p_scroll_vec);
+ void _zoom_callback(Vector2 p_scroll_vec, Vector2 p_origin);
+
bool connecting = false;
String connecting_from;
bool connecting_out = false;
@@ -136,6 +148,7 @@ private:
bool connecting_valid = false;
Vector2 click_pos;
+ PanningScheme panning_scheme = SCROLL_ZOOMS;
bool dragging = false;
bool just_selected = false;
bool moving_selection = false;
@@ -277,6 +290,9 @@ public:
void remove_valid_connection_type(int p_type, int p_with_type);
bool is_valid_connection_type(int p_type, int p_with_type) const;
+ void set_panning_scheme(PanningScheme p_scheme);
+ PanningScheme get_panning_scheme() const;
+
void set_zoom(float p_zoom);
void set_zoom_custom(float p_zoom, const Vector2 &p_center);
float get_zoom() const;
@@ -338,4 +354,6 @@ public:
GraphEdit();
};
+VARIANT_ENUM_CAST(GraphEdit::PanningScheme);
+
#endif // GRAPHEdit_H
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 1a270ff942..d6569e3de4 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -46,7 +46,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -54,7 +54,7 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
_shape();
update();
@@ -153,7 +153,7 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index 54c4835ccf..edd206a1ca 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -811,7 +811,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -819,7 +819,7 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
dirty = true;
update();
@@ -851,7 +851,7 @@ bool Label::_get(const StringName &p_name, Variant &r_ret) const {
void Label::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index f000f64caf..ec18101d2f 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -2164,7 +2164,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -2172,7 +2172,7 @@ bool LineEdit::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
_shape();
update();
@@ -2204,7 +2204,7 @@ bool LineEdit::_get(const StringName &p_name, Variant &r_ret) const {
void LineEdit::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 029ff07d13..0c313f71c2 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -97,7 +97,7 @@ private:
PopupMenu *menu_dir = nullptr;
PopupMenu *menu_ctl = nullptr;
- bool caret_mid_grapheme_enabled = false;
+ bool caret_mid_grapheme_enabled = true;
int caret_column = 0;
int scroll_offset = 0;
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index 1890e461e9..67ffa2c7ed 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -240,7 +240,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -248,7 +248,7 @@ bool LinkButton::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
_shape();
update();
@@ -280,7 +280,7 @@ bool LinkButton::_get(const StringName &p_name, Variant &r_ret) const {
void LinkButton::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 348a0324f4..863555120d 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1005,7 +1005,8 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
float y_off = TS->shaped_text_get_underline_position(rid);
float underline_width = TS->shaped_text_get_underline_thickness(rid) * get_theme_default_base_scale();
draw_line(p_ofs + Vector2(off.x, off.y + y_off), p_ofs + Vector2(off.x + glyphs[i].advance * glyphs[i].repeat, off.y + y_off), uc, underline_width);
- } else if (_find_strikethrough(it)) {
+ }
+ if (_find_strikethrough(it)) {
Color uc = font_color;
uc.a *= 0.5;
float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2;
@@ -3065,6 +3066,12 @@ void RichTextLabel::append_text(const String &p_bbcode) {
push_strikethrough();
pos = brk_end + 1;
tag_stack.push_front(tag);
+ } else if (tag == "lb") {
+ add_text("[");
+ pos = brk_end + 1;
+ } else if (tag == "rb") {
+ add_text("]");
+ pos = brk_end + 1;
} else if (tag == "lrm") {
add_text(String::chr(0x200E));
pos = brk_end + 1;
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 92da169487..bd823d12ed 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -147,6 +147,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (scrolling_enabled && buttons_visible) {
if (offset > 0) {
offset--;
+ _update_cache();
update();
}
}
@@ -154,9 +155,9 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (mb->is_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN && !mb->is_command_pressed()) {
if (scrolling_enabled && buttons_visible) {
- if (missing_right) {
+ if (missing_right && offset < tabs.size()) {
offset++;
- _ensure_no_over_offset(); // Avoid overreaching when scrolling fast.
+ _update_cache();
update();
}
}
@@ -194,12 +195,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (pos.x < decr->get_width()) {
if (missing_right) {
offset++;
+ _update_cache();
update();
}
return;
} else if (pos.x < incr->get_width() + decr->get_width()) {
if (offset > 0) {
offset--;
+ _update_cache();
update();
}
return;
@@ -209,12 +212,14 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (pos.x > limit + decr->get_width()) {
if (missing_right) {
offset++;
+ _update_cache();
update();
}
return;
} else if (pos.x > limit) {
if (offset > 0) {
offset--;
+ _update_cache();
update();
}
return;
@@ -294,7 +299,10 @@ void TabBar::_notification(int p_what) {
ensure_tab_visible(current);
} break;
case NOTIFICATION_DRAW: {
- _update_cache();
+ if (tabs.is_empty()) {
+ return;
+ }
+
RID ci = get_canvas_item();
Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected"));
@@ -304,46 +312,22 @@ void TabBar::_notification(int p_what) {
Color font_unselected_color = get_theme_color(SNAME("font_unselected_color"));
Color font_disabled_color = get_theme_color(SNAME("font_disabled_color"));
Ref<Texture2D> close = get_theme_icon(SNAME("close"));
- Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
- int outline_size = get_theme_constant(SNAME("outline_size"));
-
- Vector2 size = get_size();
- bool rtl = is_layout_rtl();
-
- int h = get_size().height;
- int w = 0;
- int mw = 0;
-
- for (int i = 0; i < tabs.size(); i++) {
- tabs.write[i].ofs_cache = mw;
- mw += get_tab_width(i);
- }
-
- if (tab_alignment == ALIGNMENT_CENTER) {
- w = (get_size().width - mw) / 2;
- } else if (tab_alignment == ALIGNMENT_RIGHT) {
- w = get_size().width - mw;
- }
-
- if (w < 0) {
- w = 0;
- }
-
Ref<Texture2D> incr = get_theme_icon(SNAME("increment"));
Ref<Texture2D> decr = get_theme_icon(SNAME("decrement"));
Ref<Texture2D> incr_hl = get_theme_icon(SNAME("increment_highlight"));
Ref<Texture2D> decr_hl = get_theme_icon(SNAME("decrement_highlight"));
+ Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
+ int outline_size = get_theme_constant(SNAME("outline_size"));
+ Vector2 size = get_size();
+ bool rtl = is_layout_rtl();
int limit = get_size().width;
- int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
-
- missing_right = false;
-
- for (int i = offset; i < tabs.size(); i++) {
- tabs.write[i].ofs_cache = w;
+ int limit_minus_buttons = limit - incr->get_width() - decr->get_width();
- int lsize = tabs[i].size_cache;
+ int h = get_size().height;
+ int w = tabs[offset].ofs_cache;
+ for (int i = offset; i <= max_drawn_tab; i++) {
Ref<StyleBox> sb;
Color col;
@@ -358,15 +342,6 @@ void TabBar::_notification(int p_what) {
col = font_unselected_color;
}
- int new_width = w + lsize;
- if (new_width > limit || (i < tabs.size() - 1 && new_width > limit_minus_buttons)) { // For the last tab, we accept if the tab covers the buttons.
- max_drawn_tab = i - 1;
- missing_right = true;
- break;
- } else {
- max_drawn_tab = i;
- }
-
Rect2 sb_rect;
if (rtl) {
sb_rect = Rect2(size.width - w - tabs[i].size_cache, 0, tabs[i].size_cache, h);
@@ -501,10 +476,6 @@ void TabBar::_notification(int p_what) {
draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
}
}
-
- buttons_visible = true;
- } else {
- buttons_visible = false;
}
} break;
}
@@ -513,6 +484,7 @@ void TabBar::_notification(int p_what) {
void TabBar::set_tab_count(int p_count) {
ERR_FAIL_COND(p_count < 0);
tabs.resize(p_count);
+ _update_cache();
update();
notify_property_list_changed();
}
@@ -560,6 +532,7 @@ void TabBar::set_tab_title(int p_tab, const String &p_title) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].text = p_title;
_shape(p_tab);
+ _update_cache();
update();
update_minimum_size();
}
@@ -588,6 +561,7 @@ void TabBar::clear_tab_opentype_features(int p_tab) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].opentype_features.clear();
_shape(p_tab);
+ _update_cache();
update();
}
@@ -597,6 +571,7 @@ void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_val
if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) {
tabs.write[p_tab].opentype_features[tag] = p_value;
_shape(p_tab);
+ _update_cache();
update();
}
}
@@ -627,6 +602,7 @@ String TabBar::get_tab_language(int p_tab) const {
void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].icon = p_icon;
+ _update_cache();
update();
update_minimum_size();
}
@@ -698,33 +674,43 @@ void TabBar::_update_hover() {
}
void TabBar::_update_cache() {
+ if (tabs.is_empty()) {
+ return;
+ }
+
Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled"));
Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected"));
Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected"));
Ref<Texture2D> incr = get_theme_icon(SNAME("increment"));
Ref<Texture2D> decr = get_theme_icon(SNAME("decrement"));
- int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
+
+ int limit = get_size().width;
+ int limit_minus_buttons = limit - incr->get_width() - decr->get_width();
int w = 0;
int mw = 0;
int size_fixed = 0;
int count_resize = 0;
+
for (int i = 0; i < tabs.size(); i++) {
- tabs.write[i].ofs_cache = mw;
+ tabs.write[i].ofs_cache = 0;
tabs.write[i].size_cache = get_tab_width(i);
tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x);
tabs.write[i].text_buf->set_width(-1);
mw += tabs[i].size_cache;
+
if (tabs[i].size_cache <= min_width || i == current) {
size_fixed += tabs[i].size_cache;
} else {
count_resize++;
}
}
+
int m_width = min_width;
if (count_resize > 0) {
m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width);
}
+
for (int i = offset; i < tabs.size(); i++) {
Ref<StyleBox> sb;
if (tabs[i].disabled) {
@@ -734,11 +720,13 @@ void TabBar::_update_cache() {
} else {
sb = tab_unselected;
}
+
int lsize = tabs[i].size_cache;
int slen = tabs[i].size_text;
if (min_width > 0 && mw > limit_minus_buttons && i != current) {
if (lsize > m_width) {
slen = m_width - (sb->get_margin(SIDE_LEFT) + sb->get_margin(SIDE_RIGHT));
+
if (tabs[i].icon.is_valid()) {
slen -= tabs[i].icon->get_width();
slen -= get_theme_constant(SNAME("hseparation"));
@@ -748,15 +736,52 @@ void TabBar::_update_cache() {
slen -= cb->get_width();
slen -= get_theme_constant(SNAME("hseparation"));
}
+
slen = MAX(slen, 1);
lsize = m_width;
}
}
+
tabs.write[i].ofs_cache = w;
tabs.write[i].size_cache = lsize;
tabs.write[i].size_text = slen;
tabs.write[i].text_buf->set_width(slen);
+
w += lsize;
+ max_drawn_tab = i;
+
+ // Check if all tabs would fit inside the area.
+ if (i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) {
+ w -= get_tab_width(i);
+ max_drawn_tab -= 1;
+
+ while (w > limit_minus_buttons && max_drawn_tab > offset) {
+ w -= get_tab_width(max_drawn_tab);
+ max_drawn_tab -= 1;
+ }
+
+ break;
+ }
+ }
+
+ missing_right = max_drawn_tab < tabs.size() - 1;
+ buttons_visible = offset > 0 || missing_right;
+
+ if (tab_alignment == ALIGNMENT_LEFT) {
+ return;
+ } else if (tab_alignment == ALIGNMENT_CENTER) {
+ w = ((buttons_visible ? limit_minus_buttons : limit) - w) / 2;
+ } else if (tab_alignment == ALIGNMENT_RIGHT) {
+ w = (buttons_visible ? limit_minus_buttons : limit) - w;
+ }
+
+ if (w < 0) {
+ w = 0;
+ }
+
+ for (int i = offset; i <= max_drawn_tab; i++) {
+ tabs.write[i].ofs_cache = w;
+ w += tabs.write[i].size_cache;
}
}
@@ -916,10 +941,10 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) {
set_current_tab(hover_now);
emit_signal(SNAME("tab_changed"), hover_now);
_update_cache();
+ update();
}
}
}
- update();
}
int TabBar::get_tab_idx_at_point(const Point2 &p_point) const {
@@ -937,6 +962,7 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const {
void TabBar::set_tab_alignment(AlignmentMode p_alignment) {
ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX);
tab_alignment = p_alignment;
+ _update_cache();
update();
}
@@ -949,6 +975,7 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) {
return;
}
clip_tabs = p_clip_tabs;
+ _update_cache();
update();
update_minimum_size();
}
@@ -1017,64 +1044,73 @@ int TabBar::get_tab_width(int p_idx) const {
}
void TabBar::_ensure_no_over_offset() {
- if (!is_inside_tree()) {
+ if (!is_inside_tree() || !buttons_visible) {
return;
}
Ref<Texture2D> incr = get_theme_icon(SNAME("increment"));
Ref<Texture2D> decr = get_theme_icon(SNAME("decrement"));
-
- int limit = get_size().width;
int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
+ int prev_offset = offset;
+
+ int total_w = tabs[max_drawn_tab].ofs_cache + tabs[max_drawn_tab].size_cache - tabs[offset].ofs_cache;
while (offset > 0) {
- int total_w = 0;
- for (int i = offset - 1; i < tabs.size(); i++) {
- total_w += tabs[i].size_cache;
- }
+ total_w += tabs[offset - 1].size_cache;
- if ((buttons_visible && total_w < limit_minus_buttons) || total_w < limit) { // For the last tab, we accept if the tab covers the buttons.
+ if (total_w < limit_minus_buttons) {
offset--;
- update();
} else {
break;
}
}
-}
-void TabBar::ensure_tab_visible(int p_idx) {
- if (!is_inside_tree()) {
- return;
+ if (prev_offset != offset) {
+ _update_cache();
+ update();
}
+}
- if (tabs.size() == 0) {
+void TabBar::ensure_tab_visible(int p_idx) {
+ if (!is_inside_tree() || !buttons_visible) {
return;
}
ERR_FAIL_INDEX(p_idx, tabs.size());
- if (p_idx == offset) {
+ if (p_idx >= offset && p_idx <= max_drawn_tab) {
return;
}
+
if (p_idx < offset) {
offset = p_idx;
+ _update_cache();
update();
+
return;
}
- int prev_offset = offset;
Ref<Texture2D> incr = get_theme_icon(SNAME("increment"));
Ref<Texture2D> decr = get_theme_icon(SNAME("decrement"));
- int limit = get_size().width;
int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
- for (int i = offset; i <= p_idx; i++) {
- int total_w = tabs[i].ofs_cache + tabs[i].size_cache;
- if (total_w > limit || (buttons_visible && total_w > limit_minus_buttons)) {
+ int total_w = tabs[max_drawn_tab].ofs_cache - tabs[offset].ofs_cache;
+ for (int i = max_drawn_tab; i <= p_idx; i++) {
+ total_w += tabs[i].size_cache;
+ }
+
+ int prev_offset = offset;
+
+ for (int i = offset; i < p_idx; i++) {
+ if (total_w > limit_minus_buttons) {
+ total_w -= tabs[i].size_cache;
offset++;
+ } else {
+ break;
}
}
if (prev_offset != offset) {
+ _update_cache();
update();
}
}
@@ -1091,6 +1127,7 @@ Rect2 TabBar::get_tab_rect(int p_tab) const {
void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX);
cb_displaypolicy = p_policy;
+ _update_cache();
update();
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 817a4453a8..8df77daafb 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1135,7 +1135,7 @@ void TextEdit::_notification(int p_what) {
int first_visible_char = TS->shaped_text_get_range(rid).y;
int last_visible_char = TS->shaped_text_get_range(rid).x;
- int char_ofs = 0;
+ float char_ofs = 0;
if (outline_size > 0 && outline_color.a > 0) {
for (int j = 0; j < gl_size; j++) {
for (int k = 0; k < glyphs[j].repeat; k++) {
@@ -1170,7 +1170,7 @@ void TextEdit::_notification(int p_what) {
}
}
- int char_pos = char_ofs + char_margin + ofs_x;
+ float char_pos = char_ofs + char_margin + ofs_x;
if (char_pos >= xmargin_beg) {
if (highlight_matching_braces_enabled) {
if ((brace_open_match_line == line && brace_open_match_column == glyphs[j].start) ||
@@ -5228,7 +5228,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
if (str.begins_with("opentype_features/")) {
String name = str.get_slicec('/', 1);
int32_t tag = TS->name_to_tag(name);
- double value = p_value;
+ int value = p_value;
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
@@ -5237,7 +5237,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
update();
}
} else {
- if ((double)opentype_features[tag] != value) {
+ if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
text.set_font_features(opentype_features);
text.invalidate_all();
@@ -5270,7 +5270,7 @@ bool TextEdit::_get(const StringName &p_name, Variant &r_ret) const {
void TextEdit::_get_property_list(List<PropertyInfo> *p_list) const {
for (const Variant *ftr = opentype_features.next(nullptr); ftr != nullptr; ftr = opentype_features.next(ftr)) {
String name = TS->tag_to_name(*ftr);
- p_list->push_back(PropertyInfo(Variant::FLOAT, "opentype_features/" + name));
+ p_list->push_back(PropertyInfo(Variant::INT, "opentype_features/" + name));
}
p_list->push_back(PropertyInfo(Variant::NIL, "opentype_features/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
}
@@ -5949,6 +5949,7 @@ void TextEdit::_update_scrollbars() {
caret.line_ofs = 0;
caret.wrap_ofs = 0;
v_scroll->set_value(0);
+ v_scroll->set_max(0);
v_scroll->hide();
}
@@ -5966,6 +5967,7 @@ void TextEdit::_update_scrollbars() {
} else {
caret.x_ofs = 0;
h_scroll->set_value(0);
+ h_scroll->set_max(0);
h_scroll->hide();
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index d51ac8dffc..57b48b5f52 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -374,7 +374,7 @@ private:
bool move_caret_on_right_click = true;
- bool caret_mid_grapheme_enabled = false;
+ bool caret_mid_grapheme_enabled = true;
bool drag_action = false;
bool drag_caret_force_displayed = false;
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index ebf5ce597e..a8cdeb44f5 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -44,9 +44,6 @@ void TextureRect::_notification(int p_what) {
bool tile = false;
switch (stretch_mode) {
- case STRETCH_SCALE_ON_EXPAND: {
- size = expand ? get_size() : texture->get_size();
- } break;
case STRETCH_SCALE: {
size = get_size();
} break;
@@ -114,7 +111,7 @@ void TextureRect::_notification(int p_what) {
}
Size2 TextureRect::get_minimum_size() const {
- if (!expand && !texture.is_null()) {
+ if (!ignore_texture_size && !texture.is_null()) {
return texture->get_size();
} else {
return Size2();
@@ -124,8 +121,8 @@ Size2 TextureRect::get_minimum_size() const {
void TextureRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TextureRect::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &TextureRect::get_texture);
- ClassDB::bind_method(D_METHOD("set_expand", "enable"), &TextureRect::set_expand);
- ClassDB::bind_method(D_METHOD("has_expand"), &TextureRect::has_expand);
+ ClassDB::bind_method(D_METHOD("set_ignore_texture_size", "ignore"), &TextureRect::set_ignore_texture_size);
+ ClassDB::bind_method(D_METHOD("get_ignore_texture_size"), &TextureRect::get_ignore_texture_size);
ClassDB::bind_method(D_METHOD("set_flip_h", "enable"), &TextureRect::set_flip_h);
ClassDB::bind_method(D_METHOD("is_flipped_h"), &TextureRect::is_flipped_h);
ClassDB::bind_method(D_METHOD("set_flip_v", "enable"), &TextureRect::set_flip_v);
@@ -134,12 +131,11 @@ void TextureRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureRect::get_stretch_mode);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand"), "set_expand", "has_expand");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale On Expand (Compat),Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_texture_size"), "set_ignore_texture_size", "get_ignore_texture_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Scale,Tile,Keep,Keep Centered,Keep Aspect,Keep Aspect Centered,Keep Aspect Covered"), "set_stretch_mode", "get_stretch_mode");
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");
- BIND_ENUM_CONSTANT(STRETCH_SCALE_ON_EXPAND);
BIND_ENUM_CONSTANT(STRETCH_SCALE);
BIND_ENUM_CONSTANT(STRETCH_TILE);
BIND_ENUM_CONSTANT(STRETCH_KEEP);
@@ -179,14 +175,14 @@ Ref<Texture2D> TextureRect::get_texture() const {
return texture;
}
-void TextureRect::set_expand(bool p_expand) {
- expand = p_expand;
+void TextureRect::set_ignore_texture_size(bool p_ignore) {
+ ignore_texture_size = p_ignore;
update();
update_minimum_size();
}
-bool TextureRect::has_expand() const {
- return expand;
+bool TextureRect::get_ignore_texture_size() const {
+ return ignore_texture_size;
}
void TextureRect::set_stretch_mode(StretchMode p_mode) {
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index ede5b7b480..7d667b25a8 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -38,7 +38,6 @@ class TextureRect : public Control {
public:
enum StretchMode {
- STRETCH_SCALE_ON_EXPAND, //default, for backwards compatibility
STRETCH_SCALE,
STRETCH_TILE,
STRETCH_KEEP,
@@ -49,11 +48,11 @@ public:
};
private:
- bool expand = false;
+ bool ignore_texture_size = false;
bool hflip = false;
bool vflip = false;
Ref<Texture2D> texture;
- StretchMode stretch_mode = STRETCH_SCALE_ON_EXPAND;
+ StretchMode stretch_mode = STRETCH_SCALE;
void _texture_changed();
@@ -66,8 +65,8 @@ public:
void set_texture(const Ref<Texture2D> &p_tex);
Ref<Texture2D> get_texture() const;
- void set_expand(bool p_expand);
- bool has_expand() const;
+ void set_ignore_texture_size(bool p_ignore);
+ bool get_ignore_texture_size() const;
void set_stretch_mode(StretchMode p_mode);
StretchMode get_stretch_mode() const;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 73d39aee8a..e46de43f1e 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -3171,7 +3171,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
if (drag_touching && !drag_touching_deaccel) {
drag_accum -= mm->get_relative().y;
v_scroll->set_value(drag_from + drag_accum);
- drag_speed = -mm->get_speed().y;
+ drag_speed = -mm->get_velocity().y;
}
}
diff --git a/scene/gui/view_panner.cpp b/scene/gui/view_panner.cpp
new file mode 100644
index 0000000000..375b3732a4
--- /dev/null
+++ b/scene/gui/view_panner.cpp
@@ -0,0 +1,136 @@
+/*************************************************************************/
+/* view_panner.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 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 "view_panner.h"
+
+#include "core/input/input.h"
+#include "core/os/keyboard.h"
+
+bool ViewPanner::gui_input(const Ref<InputEvent> &p_event, Rect2 p_canvas_rect) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid()) {
+ Vector2i scroll_vec = Vector2((mb->get_button_index() == MouseButton::WHEEL_RIGHT) - (mb->get_button_index() == MouseButton::WHEEL_LEFT), (mb->get_button_index() == MouseButton::WHEEL_DOWN) - (mb->get_button_index() == MouseButton::WHEEL_UP));
+ if (scroll_vec != Vector2()) {
+ if (control_scheme == SCROLL_PANS) {
+ if (mb->is_ctrl_pressed()) {
+ callback_helper(zoom_callback, scroll_vec, mb->get_position());
+ } else {
+ Vector2 panning;
+ if (mb->is_shift_pressed()) {
+ panning.x += mb->get_factor() * scroll_vec.y;
+ panning.y += mb->get_factor() * scroll_vec.x;
+ } else {
+ panning.y += mb->get_factor() * scroll_vec.y;
+ panning.x += mb->get_factor() * scroll_vec.x;
+ }
+ callback_helper(scroll_callback, panning);
+
+ return true;
+ }
+ } else {
+ if (mb->is_ctrl_pressed()) {
+ Vector2 panning;
+ if (mb->is_shift_pressed()) {
+ panning.x += mb->get_factor() * scroll_vec.y;
+ panning.y += mb->get_factor() * scroll_vec.x;
+ } else {
+ panning.y += mb->get_factor() * scroll_vec.y;
+ panning.x += mb->get_factor() * scroll_vec.x;
+ }
+ callback_helper(scroll_callback, panning);
+
+ return true;
+ } else if (!mb->is_shift_pressed()) {
+ callback_helper(zoom_callback, scroll_vec, mb->get_position());
+ return true;
+ }
+ }
+ }
+
+ if (mb->get_button_index() == MouseButton::MIDDLE || (mb->get_button_index() == MouseButton::RIGHT && !disable_rmb) || (mb->get_button_index() == MouseButton::LEFT && (Input::get_singleton()->is_key_pressed(Key::SPACE) || !mb->is_pressed()))) {
+ if (mb->is_pressed()) {
+ is_dragging = true;
+ } else {
+ is_dragging = false;
+ }
+ return true;
+ }
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
+ if (is_dragging) {
+ if (p_canvas_rect != Rect2()) {
+ callback_helper(pan_callback, Input::get_singleton()->warp_mouse_motion(mm, p_canvas_rect));
+ } else {
+ callback_helper(pan_callback, mm->get_relative());
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ViewPanner::callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2) {
+ if (p_callback == zoom_callback) {
+ const Variant **argptr = (const Variant **)alloca(sizeof(Variant *) * 2);
+ Variant var1 = p_arg1;
+ argptr[0] = &var1;
+ Variant var2 = p_arg2;
+ argptr[1] = &var2;
+
+ Variant result;
+ Callable::CallError ce;
+ p_callback.call(argptr, 2, result, ce);
+ } else {
+ const Variant **argptr = (const Variant **)alloca(sizeof(Variant *));
+ Variant var = p_arg1;
+ argptr[0] = &var;
+
+ Variant result;
+ Callable::CallError ce;
+ p_callback.call(argptr, 1, result, ce);
+ }
+}
+
+void ViewPanner::set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback) {
+ scroll_callback = p_scroll_callback;
+ pan_callback = p_pan_callback;
+ zoom_callback = p_zoom_callback;
+}
+
+void ViewPanner::set_control_scheme(ControlScheme p_scheme) {
+ control_scheme = p_scheme;
+}
+
+void ViewPanner::set_disable_rmb(bool p_disable) {
+ disable_rmb = p_disable;
+}
diff --git a/drivers/gles3/rasterizer_platforms.h b/scene/gui/view_panner.h
index 97a205e90d..e083d83de4 100644
--- a/drivers/gles3/rasterizer_platforms.h
+++ b/scene/gui/view_panner.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* rasterizer_platforms.h */
+/* view_panner.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,21 +28,36 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RASTERIZER_PLATFORMS_H
-#define RASTERIZER_PLATFORMS_H
+#ifndef VIEW_PANNER_H
+#define VIEW_PANNER_H
-/////////////////////////////////////////////////////
-// override for intellisense .. ONLY FOR DEVELOPMENT
-//#ifndef X11_ENABLED
-//#define X11_ENABLED
-//#endif
-//#define GLES3_BACKEND_ENABLED
-/////////////////////////////////////////////////////
+#include "core/object/ref_counted.h"
-#if defined(GLES3_ENABLED) || defined(GLES_ENABLED)
+class InputEvent;
-#define GLES3_BACKEND_ENABLED
+class ViewPanner : public RefCounted {
+ GDCLASS(ViewPanner, RefCounted);
-#endif // defined(GLES3_ENABLED) || defined(GLES_ENABLED)
+ bool is_dragging = false;
+ bool disable_rmb = false;
-#endif // RASTERIZER_PLATFORMS_H
+ Callable scroll_callback;
+ Callable pan_callback;
+ Callable zoom_callback;
+
+ void callback_helper(Callable p_callback, Vector2 p_arg1, Vector2 p_arg2 = Vector2());
+
+public:
+ enum ControlScheme {
+ SCROLL_ZOOMS,
+ SCROLL_PANS,
+ };
+ ControlScheme control_scheme = SCROLL_ZOOMS;
+
+ void set_callbacks(Callable p_scroll_callback, Callable p_pan_callback, Callable p_zoom_callback);
+ void set_control_scheme(ControlScheme p_scheme);
+ void set_disable_rmb(bool p_disable);
+ bool gui_input(const Ref<InputEvent> &p_ev, Rect2 p_canvas_rect = Rect2());
+};
+
+#endif // VIEW_PANNER_H
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 9e4908a23d..cafa4a43fd 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -535,7 +535,7 @@ void SceneTree::process_tweens(float p_delta, bool p_physics) {
for (List<Ref<Tween>>::Element *E = tweens.front(); E;) {
List<Ref<Tween>>::Element *N = E->next();
// Don't process if paused or process mode doesn't match.
- if ((paused && E->get()->should_pause()) || (p_physics == (E->get()->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) {
+ if (!E->get()->can_process(paused) || (p_physics == (E->get()->get_process_mode() == Tween::TWEEN_PROCESS_IDLE))) {
if (E == L) {
break;
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index abbd7ba5a0..4ad250ff54 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1699,13 +1699,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (over) {
Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(mpos);
- Vector2 speed = localizer.basis_xform(mm->get_speed());
+ Vector2 velocity = localizer.basis_xform(mm->get_velocity());
Vector2 rel = localizer.basis_xform(mm->get_relative());
mm = mm->xformed_by(Transform2D()); // Make a copy.
mm->set_global_position(mpos);
- mm->set_speed(speed);
+ mm->set_velocity(velocity);
mm->set_relative(rel);
if (mm->get_button_mask() == MouseButton::NONE) {
@@ -1955,12 +1955,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (over->can_process()) {
Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(drag_event->get_position());
- Vector2 speed = localizer.basis_xform(drag_event->get_speed());
+ Vector2 velocity = localizer.basis_xform(drag_event->get_velocity());
Vector2 rel = localizer.basis_xform(drag_event->get_relative());
drag_event = drag_event->xformed_by(Transform2D()); // Make a copy.
- drag_event->set_speed(speed);
+ drag_event->set_velocity(velocity);
drag_event->set_relative(rel);
drag_event->set_position(pos);
@@ -3954,8 +3954,8 @@ void SubViewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_clear_mode", "mode"), &SubViewport::set_clear_mode);
ClassDB::bind_method(D_METHOD("get_clear_mode"), &SubViewport::get_clear_mode);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size_2d_override"), "set_size_2d_override", "get_size_2d_override");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size_2d_override"), "set_size_2d_override", "get_size_2d_override");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_2d_override_stretch"), "set_size_2d_override_stretch", "is_size_2d_override_stretch_enabled");
ADD_GROUP("Render Target", "render_target_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 549bd3ba12..93c7eb43a1 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -994,7 +994,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// Visual Node Ports
theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 24 * scale);
- theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale);
+ theme->set_constant("port_grab_distance_vertical", "GraphEdit", 26 * scale);
theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0));
Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0);
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 9bd98237ff..d9e0c301de 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -184,6 +184,9 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_script_support_override", "script"), &FontData::remove_script_support_override);
ClassDB::bind_method(D_METHOD("get_script_support_overrides"), &FontData::get_script_support_overrides);
+ ClassDB::bind_method(D_METHOD("set_opentype_feature_overrides", "overrides"), &FontData::set_opentype_feature_overrides);
+ ClassDB::bind_method(D_METHOD("get_opentype_feature_overrides"), &FontData::get_opentype_feature_overrides);
+
ClassDB::bind_method(D_METHOD("has_char", "char"), &FontData::has_char);
ClassDB::bind_method(D_METHOD("get_supported_chars"), &FontData::get_supported_chars);
@@ -191,49 +194,25 @@ void FontData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_supported_feature_list"), &FontData::get_supported_feature_list);
ClassDB::bind_method(D_METHOD("get_supported_variation_list"), &FontData::get_supported_variation_list);
+
+ ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_data", "get_data");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_antialiased", "is_antialiased");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_name", "get_font_name");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style_name", "get_font_style_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_font_style", "get_font_style");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_multichannel_signed_distance_field", "is_multichannel_signed_distance_field");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_pixel_range", "get_msdf_pixel_range");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_msdf_size", "get_msdf_size");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_force_autohinter", "is_force_autohinter");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE), "set_hinting", "get_hinting");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_oversampling", "get_oversampling");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_fixed_size", "get_fixed_size");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "opentype_feature_overrides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_opentype_feature_overrides", "get_opentype_feature_overrides");
}
bool FontData::_set(const StringName &p_name, const Variant &p_value) {
Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 1) {
- if (tokens[0] == "data") {
- set_data(p_value);
- return true;
- } else if (tokens[0] == "antialiased") {
- set_antialiased(p_value);
- return true;
- } else if (tokens[0] == "font_name") {
- set_font_name(p_value);
- return true;
- } else if (tokens[0] == "style_name") {
- set_font_style_name(p_value);
- return true;
- } else if (tokens[0] == "font_style") {
- set_font_style(p_value);
- return true;
- } else if (tokens[0] == "multichannel_signed_distance_field") {
- set_multichannel_signed_distance_field(p_value);
- return true;
- } else if (tokens[0] == "msdf_pixel_range") {
- set_msdf_pixel_range(p_value);
- return true;
- } else if (tokens[0] == "msdf_size") {
- set_msdf_size(p_value);
- return true;
- } else if (tokens[0] == "fixed_size") {
- set_fixed_size(p_value);
- return true;
- } else if (tokens[0] == "hinting") {
- set_hinting((TextServer::Hinting)p_value.operator int());
- return true;
- } else if (tokens[0] == "force_autohinter") {
- set_force_autohinter(p_value);
- return true;
- } else if (tokens[0] == "oversampling") {
- set_oversampling(p_value);
- return true;
- }
- } else if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
String lang = tokens[1];
set_language_support_override(lang, p_value);
return true;
@@ -309,45 +288,7 @@ bool FontData::_set(const StringName &p_name, const Variant &p_value) {
bool FontData::_get(const StringName &p_name, Variant &r_ret) const {
Vector<String> tokens = p_name.operator String().split("/");
- if (tokens.size() == 1) {
- if (tokens[0] == "data") {
- r_ret = get_data();
- return true;
- } else if (tokens[0] == "antialiased") {
- r_ret = is_antialiased();
- return true;
- } else if (tokens[0] == "font_name") {
- r_ret = get_font_name();
- return true;
- } else if (tokens[0] == "style_name") {
- r_ret = get_font_style_name();
- return true;
- } else if (tokens[0] == "font_style") {
- r_ret = get_font_style();
- return true;
- } else if (tokens[0] == "multichannel_signed_distance_field") {
- r_ret = is_multichannel_signed_distance_field();
- return true;
- } else if (tokens[0] == "msdf_pixel_range") {
- r_ret = get_msdf_pixel_range();
- return true;
- } else if (tokens[0] == "msdf_size") {
- r_ret = get_msdf_size();
- return true;
- } else if (tokens[0] == "fixed_size") {
- r_ret = get_fixed_size();
- return true;
- } else if (tokens[0] == "hinting") {
- r_ret = get_hinting();
- return true;
- } else if (tokens[0] == "force_autohinter") {
- r_ret = is_force_autohinter();
- return true;
- } else if (tokens[0] == "oversampling") {
- r_ret = get_oversampling();
- return true;
- }
- } else if (tokens.size() == 2 && tokens[0] == "language_support_override") {
+ if (tokens.size() == 2 && tokens[0] == "language_support_override") {
String lang = tokens[1];
r_ret = get_language_support_override(lang);
return true;
@@ -422,20 +363,6 @@ bool FontData::_get(const StringName &p_name, Variant &r_ret) const {
}
void FontData::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "font_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::STRING, "style_name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "font_style", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "antialiased", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "multichannel_signed_distance_field", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "msdf_pixel_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "msdf_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "fixed_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::INT, "hinting", PROPERTY_HINT_ENUM, "None,Light,Normal", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::BOOL, "force_autohinter", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
- p_list->push_back(PropertyInfo(Variant::FLOAT, "oversampling", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
-
Vector<String> lang_over = get_language_support_overrides();
for (int i = 0; i < lang_over.size(); i++) {
p_list->push_back(PropertyInfo(Variant::BOOL, "language_support_override/" + lang_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
@@ -1077,6 +1004,16 @@ Vector<String> FontData::get_script_support_overrides() const {
return TS->font_get_script_support_overrides(cache[0]);
}
+void FontData::set_opentype_feature_overrides(const Dictionary &p_overrides) {
+ _ensure_rid(0);
+ TS->font_set_opentype_feature_overrides(cache[0], p_overrides);
+}
+
+Dictionary FontData::get_opentype_feature_overrides() const {
+ _ensure_rid(0);
+ return TS->font_get_opentype_feature_overrides(cache[0]);
+}
+
bool FontData::has_char(char32_t p_char) const {
_ensure_rid(0);
return TS->font_has_char(cache[0], p_char);
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 9c3672bd69..1b4ecc73ce 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -198,6 +198,9 @@ public:
virtual void remove_script_support_override(const String &p_script);
virtual Vector<String> get_script_support_overrides() const;
+ virtual void set_opentype_feature_overrides(const Dictionary &p_overrides);
+ virtual Dictionary get_opentype_feature_overrides() const;
+
// Base font properties.
virtual bool has_char(char32_t p_char) const;
virtual String get_supported_chars() const;
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 7250544d10..57591bee2f 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -35,7 +35,6 @@
#include "core/templates/self_list.h"
#include "scene/resources/shader.h"
#include "scene/resources/texture.h"
-#include "servers/rendering/shader_language.h"
#include "servers/rendering_server.h"
class Material : public Resource {
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 75ea6a0f12..aa9682bd80 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -36,11 +36,10 @@
///@TODO probably should change a few integers to unsigned integers...
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
This class is set apart that it assumes a single surface is always generated for our mesh.
*/
+
class PrimitiveMesh : public Mesh {
GDCLASS(PrimitiveMesh, Mesh);
diff --git a/scene/resources/separation_ray_shape_2d.cpp b/scene/resources/separation_ray_shape_2d.cpp
index 5ac8d0a475..0406c91b70 100644
--- a/scene/resources/separation_ray_shape_2d.cpp
+++ b/scene/resources/separation_ray_shape_2d.cpp
@@ -59,15 +59,13 @@ void SeparationRayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
xf.rotate(target_position.angle());
xf.translate(Vector2(no_line ? 0 : target_position.length() - arrow_size, 0));
- Vector<Vector2> pts;
- pts.push_back(xf.xform(Vector2(arrow_size, 0)));
- pts.push_back(xf.xform(Vector2(0, 0.5 * arrow_size)));
- pts.push_back(xf.xform(Vector2(0, -0.5 * arrow_size)));
-
- Vector<Color> cols;
- for (int i = 0; i < 3; i++) {
- cols.push_back(p_color);
- }
+ Vector<Vector2> pts = {
+ xf.xform(Vector2(arrow_size, 0)),
+ xf.xform(Vector2(0, 0.5 * arrow_size)),
+ xf.xform(Vector2(0, -0.5 * arrow_size))
+ };
+
+ Vector<Color> cols = { p_color, p_color, p_color };
RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
}
diff --git a/scene/resources/separation_ray_shape_3d.cpp b/scene/resources/separation_ray_shape_3d.cpp
index a059d55bbe..5aa7616589 100644
--- a/scene/resources/separation_ray_shape_3d.cpp
+++ b/scene/resources/separation_ray_shape_3d.cpp
@@ -33,9 +33,10 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> SeparationRayShape3D::get_debug_mesh_lines() const {
- Vector<Vector3> points;
- points.push_back(Vector3());
- points.push_back(Vector3(0, 0, get_length()));
+ Vector<Vector3> points = {
+ Vector3(),
+ Vector3(0, 0, get_length())
+ };
return points;
}
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index c39902739f..5afd424e03 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -521,21 +521,22 @@ inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color
set_inner_corner_radius(style_rect, ring_rect, corner_radius, ring_corner_radius);
// Corner radius center points.
- Vector<Point2> outer_points;
- outer_points.push_back(ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0])); //tl
- outer_points.push_back(Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1])); //tr
- outer_points.push_back(ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2])); //br
- outer_points.push_back(Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3])); //bl
+ Vector<Point2> outer_points = {
+ ring_rect.position + Vector2(ring_corner_radius[0], ring_corner_radius[0]), //tl
+ Point2(ring_rect.position.x + ring_rect.size.x - ring_corner_radius[1], ring_rect.position.y + ring_corner_radius[1]), //tr
+ ring_rect.position + ring_rect.size - Vector2(ring_corner_radius[2], ring_corner_radius[2]), //br
+ Point2(ring_rect.position.x + ring_corner_radius[3], ring_rect.position.y + ring_rect.size.y - ring_corner_radius[3]) //bl
+ };
real_t inner_corner_radius[4];
set_inner_corner_radius(style_rect, inner_rect, corner_radius, inner_corner_radius);
- Vector<Point2> inner_points;
- inner_points.push_back(inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0])); //tl
- inner_points.push_back(Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1])); //tr
- inner_points.push_back(inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2])); //br
- inner_points.push_back(Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3])); //bl
-
+ Vector<Point2> inner_points = {
+ inner_rect.position + Vector2(inner_corner_radius[0], inner_corner_radius[0]), //tl
+ Point2(inner_rect.position.x + inner_rect.size.x - inner_corner_radius[1], inner_rect.position.y + inner_corner_radius[1]), //tr
+ inner_rect.position + inner_rect.size - Vector2(inner_corner_radius[2], inner_corner_radius[2]), //br
+ Point2(inner_rect.position.x + inner_corner_radius[3], inner_rect.position.y + inner_rect.size.y - inner_corner_radius[3]) //bl
+ };
// Calculate the vertices.
for (int corner_index = 0; corner_index < 4; corner_index++) {
for (int detail = 0; detail <= adapted_corner_detail; detail++) {
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 44a7af75b9..ddb9cc7440 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1765,11 +1765,14 @@ Vector<Point2> TileSet::_get_square_corner_or_side_terrain_bit_polygon(Vector2i
break;
}
bit_rect.position *= Vector2(p_size) / 6.0;
- Vector<Vector2> polygon;
- polygon.push_back(bit_rect.position);
- polygon.push_back(Vector2(bit_rect.get_end().x, bit_rect.position.y));
- polygon.push_back(bit_rect.get_end());
- polygon.push_back(Vector2(bit_rect.position.x, bit_rect.get_end().y));
+
+ Vector<Vector2> polygon = {
+ bit_rect.position,
+ Vector2(bit_rect.get_end().x, bit_rect.position.y),
+ bit_rect.get_end(),
+ Vector2(bit_rect.position.x, bit_rect.get_end().y)
+ };
+
return polygon;
}
@@ -1984,25 +1987,26 @@ Vector<Point2> TileSet::_get_isometric_side_terrain_bit_polygon(Vector2i p_size,
}
Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(1, 3.0 - p_overlap * 2.0));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-1, 3.0 - p_overlap * 2.0));
- point_list.push_back(Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(-1, -(3.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(1, -(3.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0));
+ Vector<Vector2> point_list = {
+ Vector2(3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(1, 3.0 - p_overlap * 2.0),
+ Vector2(0, 3),
+ Vector2(-1, 3.0 - p_overlap * 2.0),
+ Vector2(-2, 3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, (3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(-3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(-1, -(3.0 - p_overlap * 2.0)),
+ Vector2(0, -3),
+ Vector2(1, -(3.0 - p_overlap * 2.0)),
+ Vector2(2, -3.0 * (1.0 - (p_overlap * 2.0) * 2.0 / 3.0)),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(3, -(3.0 * (1.0 - p_overlap * 2.0)) / 2.0)
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
@@ -2144,19 +2148,20 @@ Vector<Point2> TileSet::_get_half_offset_corner_or_side_terrain_bit_polygon(Vect
}
Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, 0));
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, 0));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
+ Vector<Vector2> point_list = {
+ Vector2(3, 0),
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(0, 3),
+ Vector2(-1.5, (3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, 0),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(0, -3),
+ Vector2(1.5, -(3.0 * (1.0 - p_overlap * 2.0) + 3.0) / 2.0),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
@@ -2250,13 +2255,14 @@ Vector<Point2> TileSet::_get_half_offset_corner_terrain_bit_polygon(Vector2i p_s
}
Vector<Point2> TileSet::_get_half_offset_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis) {
- Vector<Vector2> point_list;
- point_list.push_back(Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, 3));
- point_list.push_back(Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)));
- point_list.push_back(Vector2(0, -3));
- point_list.push_back(Vector2(3, -3.0 * (1.0 - p_overlap * 2.0)));
+ Vector<Vector2> point_list = {
+ Vector2(3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(0, 3),
+ Vector2(-3, 3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(-3, -3.0 * (1.0 - p_overlap * 2.0)),
+ Vector2(0, -3),
+ Vector2(3, -3.0 * (1.0 - p_overlap * 2.0))
+ };
Vector2 unit = Vector2(p_size) / 6.0;
for (int i = 0; i < point_list.size(); i++) {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 57b73c1234..ece1ba1972 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -2015,7 +2015,7 @@ void VisualShader::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_shader"), &VisualShader::_update_shader);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_graph_offset", "get_graph_offset");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "engine_version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_engine_version", "get_engine_version");
ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs.
diff --git a/scene/resources/world_boundary_shape_3d.cpp b/scene/resources/world_boundary_shape_3d.cpp
index efa288511d..09d41e8291 100644
--- a/scene/resources/world_boundary_shape_3d.cpp
+++ b/scene/resources/world_boundary_shape_3d.cpp
@@ -34,7 +34,6 @@
Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const {
Plane p = get_plane();
- Vector<Vector3> points;
Vector3 n1 = p.get_any_perpendicular_normal();
Vector3 n2 = p.normal.cross(n1).normalized();
@@ -46,16 +45,18 @@ Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const {
p.normal * p.d + n1 * -10.0 + n2 * 10.0,
};
- points.push_back(pface[0]);
- points.push_back(pface[1]);
- points.push_back(pface[1]);
- points.push_back(pface[2]);
- points.push_back(pface[2]);
- points.push_back(pface[3]);
- points.push_back(pface[3]);
- points.push_back(pface[0]);
- points.push_back(p.normal * p.d);
- points.push_back(p.normal * p.d + p.normal * 3);
+ Vector<Vector3> points = {
+ pface[0],
+ pface[1],
+ pface[1],
+ pface[2],
+ pface[2],
+ pface[3],
+ pface[3],
+ pface[0],
+ p.normal * p.d,
+ p.normal * p.d + p.normal * 3
+ };
return points;
}
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index 74280ee22e..d6293bf875 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -28,18 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-// Author: reduzio@gmail.com (C) 2006
-
#ifndef EQ_FILTER_H
#define EQ_FILTER_H
#include "core/templates/vector.h"
#include "core/typedefs.h"
-/**
-@author Juan Linietsky
-*/
-
class EQ {
public:
enum Preset {
@@ -105,4 +99,4 @@ inline void EQ::BandProcess::process_one(float &p_data) {
history.b2 = history.b1;
}
-#endif
+#endif // EQ_FILTER_H
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index fa06d262a3..ff59ab8d82 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -28,8 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006
-
#ifndef REVERB_H
#define REVERB_H
@@ -120,4 +118,4 @@ public:
~Reverb();
};
-#endif
+#endif // REVERB_H
diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h
index ea66c5f947..e86605a89b 100644
--- a/servers/camera/camera_feed.h
+++ b/servers/camera/camera_feed.h
@@ -37,8 +37,6 @@
#include "servers/rendering_server.h"
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The camera server is a singleton object that gives access to the various
camera feeds that can be used as the background for our environment.
**/
@@ -111,4 +109,4 @@ public:
VARIANT_ENUM_CAST(CameraFeed::FeedDataType);
VARIANT_ENUM_CAST(CameraFeed::FeedPosition);
-#endif /* !CAMERA_FEED_H */
+#endif // CAMERA_FEED_H
diff --git a/servers/camera_server.h b/servers/camera_server.h
index 893fdba912..b70938c34f 100644
--- a/servers/camera_server.h
+++ b/servers/camera_server.h
@@ -38,8 +38,6 @@
#include "core/variant/variant.h"
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The camera server is a singleton object that gives access to the various
camera feeds that can be used as the background for our environment.
**/
@@ -113,4 +111,4 @@ public:
VARIANT_ENUM_CAST(CameraServer::FeedImage);
-#endif /* CAMERA_SERVER_H */
+#endif // CAMERA_SERVER_H
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 53190d7681..ee196673a3 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -29,14 +29,11 @@
/*************************************************************************/
#include "servers/navigation_server_2d.h"
+
#include "core/math/transform_2d.h"
#include "core/math/transform_3d.h"
#include "servers/navigation_server_3d.h"
-/**
- @author AndreaCatania
-*/
-
NavigationServer2D *NavigationServer2D::singleton = nullptr;
#define FORWARD_0_C(FUNC_NAME) \
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index 2dd718e09c..7350eeb5b1 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -28,12 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
- @author AndreaCatania
-*/
-
-#ifndef NAVIGATION_2D_SERVER_H
-#define NAVIGATION_2D_SERVER_H
+#ifndef NAVIGATION_SERVER_2D_H
+#define NAVIGATION_SERVER_2D_H
#include "core/object/class_db.h"
#include "core/templates/rid.h"
@@ -171,4 +167,4 @@ public:
virtual ~NavigationServer2D();
};
-#endif
+#endif // NAVIGATION_SERVER_2D_H
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index d78e58bea0..d18777869a 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -28,10 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
- @author AndreaCatania
-*/
-
#include "navigation_server_3d.h"
NavigationServer3D *NavigationServer3D::singleton = nullptr;
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index f711e4e0e5..0a75b07931 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -28,12 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/**
- @author AndreaCatania
-*/
-
-#ifndef NAVIGATION_SERVER_H
-#define NAVIGATION_SERVER_H
+#ifndef NAVIGATION_SERVER_3D_H
+#define NAVIGATION_SERVER_3D_H
#include "core/object/class_db.h"
#include "core/templates/rid.h"
@@ -205,4 +201,4 @@ public:
static NavigationServer3D *new_default_server();
};
-#endif
+#endif // NAVIGATION_SERVER_3D_H
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index cd7b2622ab..36604073cc 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1795,12 +1795,14 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
{
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set);
//regular forward for now
- Vector<Color> clear;
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
+ Vector<Color> clear = {
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0)
+ };
+
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
@@ -1839,12 +1841,13 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p
{
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true);
//regular forward for now
- Vector<Color> clear;
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
+ Vector<Color> clear = {
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0)
+ };
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
const int uv_offset_count = 9;
@@ -1901,11 +1904,12 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
Vector3 half_extents = p_bounds.size * 0.5;
Vector3 center = p_bounds.position + half_extents;
- Vector<RID> sbs;
- sbs.push_back(p_albedo_texture);
- sbs.push_back(p_emission_texture);
- sbs.push_back(p_emission_aniso_texture);
- sbs.push_back(p_geom_facing_texture);
+ Vector<RID> sbs = {
+ p_albedo_texture,
+ p_emission_texture,
+ p_emission_aniso_texture,
+ p_geom_facing_texture
+ };
//print_line("re-render " + p_from + " - " + p_size + " bounds " + p_bounds);
for (int i = 0; i < 3; i++) {
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 942e78e1ff..a27ea75017 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -48,7 +48,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
@@ -79,10 +79,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
int depth_drawi = DEPTH_DRAW_OPAQUE;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
- actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
- actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
+ actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
+ actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@@ -157,10 +157,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
}
print_line("\n**uniforms:\n" + gen_code.uniforms);
- print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]);
- print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]);
+ print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
+ print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
- shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
+ shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -510,7 +510,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
{
//shader compiler
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index 98448ce846..8e7bbad63e 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -129,7 +129,7 @@ public:
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@@ -208,7 +208,7 @@ public:
}
SceneForwardClusteredShaderRD shader;
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
RID default_shader;
RID default_material;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 8b2a60c487..b9c51f5461 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1002,12 +1002,13 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
{
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0);
//regular forward for now
- Vector<Color> clear;
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
+ Vector<Color> clear = {
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0)
+ };
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
_render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), &render_list_params, 0, render_list_params.element_count);
RD::get_singleton()->draw_list_end();
@@ -1043,12 +1044,14 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in
{
RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, 0);
//regular forward for now
- Vector<Color> clear;
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
- clear.push_back(Color(0, 0, 0, 0));
+ Vector<Color> clear = {
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0),
+ Color(0, 0, 0, 0)
+ };
+
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
const int uv_offset_count = 9;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index b0cc26340d..1613a307ec 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -51,7 +51,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
@@ -81,10 +81,10 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
int depth_drawi = DEPTH_DRAW_OPAQUE;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
- actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
- actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
+ actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
+ actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@@ -159,11 +159,11 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
}
print_line("\n**uniforms:\n" + gen_code.uniforms);
- print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX]);
- print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT]);
+ print_line("\n**vertex_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX]);
+ print_line("\n**fragment_globals:\n" + gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT]);
#endif
- shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
+ shader_singleton->shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -498,7 +498,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
{
//shader compiler
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["WORLD_MATRIX"] = "world_matrix";
actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index 770f9bde3b..c136afd9f3 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -105,7 +105,7 @@ public:
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@@ -184,7 +184,7 @@ public:
}
SceneForwardMobileShaderRD shader;
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
RID default_shader;
RID default_material;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index da75c70cbb..7e188926e0 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -1957,15 +1957,15 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
+ ShaderCompiler::GeneratedCode gen_code;
int blend_mode = BLEND_MODE_MIX;
uses_screen_texture = false;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["vertex"] = ShaderCompilerRD::STAGE_VERTEX;
- actions.entry_point_stages["fragment"] = ShaderCompilerRD::STAGE_FRAGMENT;
- actions.entry_point_stages["light"] = ShaderCompilerRD::STAGE_FRAGMENT;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["vertex"] = ShaderCompiler::STAGE_VERTEX;
+ actions.entry_point_stages["fragment"] = ShaderCompiler::STAGE_FRAGMENT;
+ actions.entry_point_stages["light"] = ShaderCompiler::STAGE_FRAGMENT;
actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
@@ -2002,7 +2002,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
print_line("\n**fragment_code:\n" + gen_code.fragment);
print_line("\n**light_code:\n" + gen_code.light);
#endif
- canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
+ canvas_singleton->shader.canvas_shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!canvas_singleton->shader.canvas_shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -2359,7 +2359,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
{
//shader compiler
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["VERTEX"] = "vertex";
actions.renames["LIGHT_VERTEX"] = "light_vertex";
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index c9544a5239..b409264c9a 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -35,10 +35,10 @@
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/shader_compiler.h"
class RendererCanvasRenderRD : public RendererCanvasRender {
RendererStorageRD *storage;
@@ -148,7 +148,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
RID default_skeleton_uniform_buffer;
RID default_skeleton_texture_buffer;
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
} shader;
struct ShaderData : public RendererStorageRD::ShaderData {
@@ -167,7 +167,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
String path;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 77843ceee5..a499cedd2c 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -3837,9 +3837,9 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["fog"] = ShaderCompilerRD::STAGE_COMPUTE;
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["fog"] = ShaderCompiler::STAGE_COMPUTE;
uses_time = false;
@@ -3856,7 +3856,7 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
version = scene_singleton->volumetric_fog.shader.version_create();
}
- scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines);
+ scene_singleton->volumetric_fog.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines);
ERR_FAIL_COND(!scene_singleton->volumetric_fog.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -5653,7 +5653,7 @@ void RendererSceneRenderRD::init() {
}
{
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["TIME"] = "scene_params.time";
actions.renames["PI"] = _MKSTR(Math_PI);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index b8a088d041..6432ca99f0 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -834,7 +834,7 @@ private:
float transform[16];
};
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
VolumetricFogShaderRD shader;
FogPushConstant push_constant;
RID volume_ubo;
@@ -917,7 +917,7 @@ private:
RID pipeline;
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 8fb3c607fa..f0419b7907 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -50,9 +50,9 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["sky"] = ShaderCompilerRD::STAGE_FRAGMENT;
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["sky"] = ShaderCompiler::STAGE_FRAGMENT;
uses_time = false;
uses_half_res = false;
@@ -112,7 +112,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
print_line("\n**light_code:\n" + gen_code.light);
#endif
- scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_VERTEX], gen_code.stage_globals[ShaderCompilerRD::STAGE_FRAGMENT], gen_code.defines);
+ scene_singleton->sky.sky_shader.shader.version_set_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_VERTEX], gen_code.stage_globals[ShaderCompiler::STAGE_FRAGMENT], gen_code.defines);
ERR_FAIL_COND(!scene_singleton->sky.sky_shader.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -807,7 +807,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_SKY, _create_sky_material_funcs);
{
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["COLOR"] = "color";
actions.renames["ALPHA"] = "alpha";
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 1359cdec67..46d376e667 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -111,7 +111,7 @@ private:
PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
@@ -220,7 +220,7 @@ public:
struct SkyShader {
SkyShaderRD shader;
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
RID default_shader;
RID default_material;
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 932cdcaea8..af025dc7bc 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -2710,7 +2710,7 @@ RendererStorageRD::MaterialData::~MaterialData() {
}
}
-void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
+void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
RendererStorageRD *singleton = (RendererStorageRD *)RendererStorage::base_singleton;
#ifdef TOOLS_ENABLED
Texture *roughness_detect_texture = nullptr;
@@ -2936,7 +2936,7 @@ void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_
}
}
-bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
+bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
if ((uint32_t)ubo_data.size() != p_ubo_size) {
p_uniform_dirty = true;
if (uniform_buffer.is_valid()) {
@@ -5812,10 +5812,10 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
return; //just invalid, but no error
}
- ShaderCompilerRD::GeneratedCode gen_code;
- ShaderCompilerRD::IdentifierActions actions;
- actions.entry_point_stages["start"] = ShaderCompilerRD::STAGE_COMPUTE;
- actions.entry_point_stages["process"] = ShaderCompilerRD::STAGE_COMPUTE;
+ ShaderCompiler::GeneratedCode gen_code;
+ ShaderCompiler::IdentifierActions actions;
+ actions.entry_point_stages["start"] = ShaderCompiler::STAGE_COMPUTE;
+ actions.entry_point_stages["process"] = ShaderCompiler::STAGE_COMPUTE;
/*
uses_time = false;
@@ -5837,7 +5837,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
version = base_singleton->particles_shader.shader.version_create();
}
- base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompilerRD::STAGE_COMPUTE], gen_code.defines);
+ base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines);
ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version));
ubo_size = gen_code.uniform_total_size;
@@ -10016,7 +10016,7 @@ RendererStorageRD::RendererStorageRD() {
material_set_data_request_function(RendererStorageRD::SHADER_TYPE_PARTICLES, _create_particles_material_funcs);
{
- ShaderCompilerRD::DefaultIdentifierActions actions;
+ ShaderCompiler::DefaultIdentifierActions actions;
actions.renames["COLOR"] = "PARTICLE.color";
actions.renames["VELOCITY"] = "PARTICLE.velocity";
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index cca61008c7..8c04274c3f 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -36,7 +36,6 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/effects_rd.h"
-#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
@@ -44,6 +43,7 @@
#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/shader_compiler.h"
class RendererStorageRD : public RendererStorage {
public:
static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
@@ -152,7 +152,7 @@ public:
struct MaterialData {
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
- void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
+ void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
@@ -160,7 +160,7 @@ public:
virtual ~MaterialData();
//to be used internally by update_parameters, in the most common configuration of material parameters
- bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void free_parameters_uniform_set(RID p_uniform_set);
private:
@@ -826,7 +826,7 @@ private:
};
ParticlesShaderRD shader;
- ShaderCompilerRD compiler;
+ ShaderCompiler compiler;
RID default_shader;
RID default_material;
@@ -877,7 +877,7 @@ private:
//PipelineCacheRD pipelines[SKY_VERSION_MAX];
Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+ Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms;
Vector<uint32_t> ubo_offsets;
uint32_t ubo_size;
diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 06f78ab193..8e57f0d9af 100644
--- a/servers/rendering/renderer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -40,11 +40,6 @@
#include "core/variant/variant.h"
#include "servers/rendering_server.h"
-#include <stdio.h>
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-
class ShaderRD {
//versions
CharString general_defines;
@@ -173,4 +168,4 @@ public:
virtual ~ShaderRD();
};
-#endif
+#endif // SHADER_RD_H
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 47934e7299..17a665922f 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -582,6 +582,21 @@ void RendererViewport::draw_viewports() {
bool visible = vp->viewport_to_screen_rect != Rect2();
+ if (vp->use_xr && xr_interface.is_valid()) {
+ visible = true; // XR viewport is always visible regardless of update mode, output is sent to HMD.
+
+ // Override our size, make sure it matches our required size and is created as a stereo target
+ Size2 xr_size = xr_interface->get_render_target_size();
+
+ // Would have been nice if we could call viewport_set_size here,
+ // but alas that takes our RID and we now have our pointer,
+ // also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
+ vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
+ vp->size = xr_size;
+ uint32_t view_count = xr_interface->get_view_count();
+ RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
+ }
+
if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) {
visible = true;
}
@@ -619,11 +634,6 @@ void RendererViewport::draw_viewports() {
RSG::storage->render_target_set_as_unused(vp->render_target);
if (vp->use_xr && xr_interface.is_valid()) {
- // override our size, make sure it matches our required size and is created as a stereo target
- vp->size = xr_interface->get_render_target_size();
- uint32_t view_count = xr_interface->get_view_count();
- RSG::storage->render_target_set_size(vp->render_target, vp->internal_size.x, vp->internal_size.y, view_count);
-
// check for an external texture destination (disabled for now, not yet supported)
// RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
@@ -843,7 +853,7 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
// if render_direct_to_screen was used, reset size and position
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
- RSG::storage->render_target_set_size(viewport->render_target, viewport->internal_size.x, viewport->internal_size.y, viewport->get_view_count());
+ RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
}
viewport->viewport_to_screen_rect = Rect2();
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/shader_compiler.cpp
index 38ac00176f..114e7e66cb 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/shader_compiler.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* shader_compiler_rd.cpp */
+/* shader_compiler.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "shader_compiler_rd.h"
+#include "shader_compiler.h"
#include "core/config/project_settings.h"
#include "core/os/os.h"
-#include "renderer_storage_rd.h"
+#include "servers/rendering/shader_types.h"
#include "servers/rendering_server.h"
#define SL ShaderLanguage
@@ -277,7 +277,7 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
}
}
-String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) {
+String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat) {
if (p_filter == ShaderLanguage::FILTER_DEFAULT) {
ERR_FAIL_COND_V(actions.default_filter == ShaderLanguage::FILTER_DEFAULT, String());
p_filter = actions.default_filter;
@@ -289,7 +289,7 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte
return actions.sampler_array_name + "[" + itos(p_filter + (p_repeat == ShaderLanguage::REPEAT_ENABLE ? ShaderLanguage::FILTER_DEFAULT : 0)) + "]";
}
-void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
+void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
int fidx = -1;
for (int i = 0; i < p_node->functions.size(); i++) {
@@ -435,7 +435,7 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c
}
}
-String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
+String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_use_scope) {
String code;
switch (p_node->type) {
@@ -1332,12 +1332,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
return code;
}
-ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &p_type) {
- RS::GlobalVariableType gvt = ((RendererStorageRD *)(RendererStorage::base_singleton))->global_variable_get_type_internal(p_type);
- return RS::global_variable_type_get_shader_datatype(gvt);
+ShaderLanguage::DataType ShaderCompiler::_get_variable_type(const StringName &p_type) {
+ RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_type);
+ return (ShaderLanguage::DataType)RS::global_variable_type_get_shader_datatype(gvt);
}
-Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
+Error ShaderCompiler::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
SL::ShaderCompileInfo info;
info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
@@ -1383,7 +1383,7 @@ Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, Ide
return OK;
}
-void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) {
+void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) {
actions = p_actions;
time_name = "TIME";
@@ -1405,7 +1405,7 @@ void ShaderCompilerRD::initialize(DefaultIdentifierActions p_actions) {
texture_functions.insert("texelFetch");
}
-ShaderCompilerRD::ShaderCompilerRD() {
+ShaderCompiler::ShaderCompiler() {
#if 0
/** SPATIAL SHADER **/
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/shader_compiler.h
index 5670d881f6..8f0ee664ac 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.h
+++ b/servers/rendering/shader_compiler.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* shader_compiler_rd.h */
+/* shader_compiler.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,15 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SHADER_COMPILER_RD_H
-#define SHADER_COMPILER_RD_H
+#ifndef SHADER_COMPILER_H
+#define SHADER_COMPILER_H
#include "core/templates/pair.h"
#include "servers/rendering/shader_language.h"
-#include "servers/rendering/shader_types.h"
#include "servers/rendering_server.h"
-class ShaderCompilerRD {
+class ShaderCompiler {
public:
enum Stage {
STAGE_VERTEX,
@@ -127,7 +126,7 @@ public:
Error compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code);
void initialize(DefaultIdentifierActions p_actions);
- ShaderCompilerRD();
+ ShaderCompiler();
};
-#endif // SHADERCOMPILERRD_H
+#endif // SHADER_COMPILER_H
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 5d420ba48d..adbcdedacc 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -7596,8 +7596,16 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
#ifdef DEBUG_ENABLED
int uniform_buffer_size = 0;
int max_uniform_buffer_size = 0;
- if (RenderingDevice::get_singleton()) {
- max_uniform_buffer_size = RenderingDevice::get_singleton()->limit_get(RenderingDevice::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ int uniform_buffer_exceeded_line = -1;
+
+ bool check_device_limit_warnings = false;
+ {
+ RenderingDevice *device = RenderingDevice::get_singleton();
+ if (device != nullptr) {
+ check_device_limit_warnings = check_warnings && HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG);
+
+ max_uniform_buffer_size = device->limit_get(RenderingDevice::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ }
}
#endif // DEBUG_ENABLED
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
@@ -8001,15 +8009,21 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
uniform2.order = uniforms++;
#ifdef DEBUG_ENABLED
- if (uniform2.array_size > 0) {
- int size = get_datatype_size(uniform2.type) * uniform2.array_size;
- int m = (16 * uniform2.array_size);
- if ((size % m) != 0U) {
- size += m - (size % m);
+ if (check_device_limit_warnings) {
+ if (uniform2.array_size > 0) {
+ int size = get_datatype_size(uniform2.type) * uniform2.array_size;
+ int m = (16 * uniform2.array_size);
+ if ((size % m) != 0U) {
+ size += m - (size % m);
+ }
+ uniform_buffer_size += size;
+ } else {
+ uniform_buffer_size += get_datatype_size(uniform2.type);
+ }
+
+ if (uniform_buffer_exceeded_line == -1 && uniform_buffer_size > max_uniform_buffer_size) {
+ uniform_buffer_exceeded_line = tk_line;
}
- uniform_buffer_size += size;
- } else {
- uniform_buffer_size += get_datatype_size(uniform2.type);
}
#endif // DEBUG_ENABLED
}
@@ -9022,11 +9036,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
#ifdef DEBUG_ENABLED
- if (HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED) && (uniform_buffer_size > max_uniform_buffer_size)) {
- Vector<Variant> args;
- args.push_back(uniform_buffer_size);
- args.push_back(max_uniform_buffer_size);
- _add_global_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, "uniform buffer", args);
+ if (check_device_limit_warnings && uniform_buffer_exceeded_line != -1) {
+ _add_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, uniform_buffer_exceeded_line, "uniform buffer", { uniform_buffer_size, max_uniform_buffer_size });
}
#endif // DEBUG_ENABLED
return OK;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index a94f70e20f..793c6f1379 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_server_globals.h"
+#include "servers/rendering/shader_language.h"
RenderingServer *RenderingServer::singleton = nullptr;
RenderingServer *(*RenderingServer::create_func)() = nullptr;
@@ -1411,7 +1412,7 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su
}
#endif
-ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) {
+int RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) {
switch (p_type) {
case RS::GLOBAL_VAR_TYPE_BOOL:
return ShaderLanguage::TYPE_BOOL;
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index ada50292fc..5dbec04665 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -41,7 +41,6 @@
#include "servers/display_server.h"
#include "servers/rendering/renderer_thread_pool.h"
#include "servers/rendering/rendering_device.h"
-#include "servers/rendering/shader_language.h"
class RenderingServer : public Object {
GDCLASS(RenderingServer, Object);
@@ -1456,7 +1455,7 @@ public:
virtual void global_variables_load_settings(bool p_load_textures) = 0;
virtual void global_variables_clear() = 0;
- static ShaderLanguage::DataType global_variable_type_get_shader_datatype(GlobalVariableType p_type);
+ static int global_variable_type_get_shader_datatype(GlobalVariableType p_type);
/* FREE */
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index 2b0510680e..a51b62e730 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -174,6 +174,9 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_font_remove_script_support_override, "font_rid", "script");
GDVIRTUAL_BIND(_font_get_script_support_overrides, "font_rid");
+ GDVIRTUAL_BIND(_font_set_opentype_feature_overrides, "font_rid", "overrides");
+ GDVIRTUAL_BIND(_font_get_opentype_feature_overrides, "font_rid");
+
GDVIRTUAL_BIND(_font_supported_feature_list, "font_rid");
GDVIRTUAL_BIND(_font_supported_variation_list, "font_rid");
@@ -869,6 +872,18 @@ Vector<String> TextServerExtension::font_get_script_support_overrides(RID p_font
return Vector<String>();
}
+void TextServerExtension::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) {
+ GDVIRTUAL_CALL(_font_set_opentype_feature_overrides, p_font_rid, p_overrides);
+}
+
+Dictionary TextServerExtension::font_get_opentype_feature_overrides(RID p_font_rid) const {
+ Dictionary ret;
+ if (GDVIRTUAL_CALL(_font_get_opentype_feature_overrides, p_font_rid, ret)) {
+ return ret;
+ }
+ return Dictionary();
+}
+
Dictionary TextServerExtension::font_supported_feature_list(RID p_font_rid) const {
Dictionary ret;
if (GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret)) {
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 5c97401118..9b456c2dd7 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -285,6 +285,11 @@ public:
GDVIRTUAL2(_font_remove_script_support_override, RID, const String &);
GDVIRTUAL1R(Vector<String>, _font_get_script_support_overrides, RID);
+ virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
+ virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_opentype_feature_overrides, RID, const Dictionary &);
+ GDVIRTUAL1RC(Dictionary, _font_get_opentype_feature_overrides, RID);
+
virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID);
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index d547bcc75e..143cda985d 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -327,6 +327,9 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_remove_script_support_override", "font_rid", "script"), &TextServer::font_remove_script_support_override);
ClassDB::bind_method(D_METHOD("font_get_script_support_overrides", "font_rid"), &TextServer::font_get_script_support_overrides);
+ ClassDB::bind_method(D_METHOD("font_set_opentype_feature_overrides", "font_rid", "overrides"), &TextServer::font_set_opentype_feature_overrides);
+ ClassDB::bind_method(D_METHOD("font_get_opentype_feature_overrides", "font_rid"), &TextServer::font_get_opentype_feature_overrides);
+
ClassDB::bind_method(D_METHOD("font_supported_feature_list", "font_rid"), &TextServer::font_supported_feature_list);
ClassDB::bind_method(D_METHOD("font_supported_variation_list", "font_rid"), &TextServer::font_supported_variation_list);
@@ -989,9 +992,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
}
real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start);
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
- ranges.push_back(Vector2(off, off + char_adv * (start - glyphs[i].start)));
+ ranges.push_back(Vector2(off, off + char_adv * (glyphs[i].end - start)));
} else {
- ranges.push_back(Vector2(off + char_adv * (glyphs[i].end - start), off + advance));
+ ranges.push_back(Vector2(off + char_adv * (start - glyphs[i].start), off + advance));
}
}
// Selection range is within grapheme.
@@ -1099,6 +1102,31 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) cons
return glyphs[i].start;
}
}
+ // Ligature, handle mid-grapheme hit.
+ if (p_coords >= off && p_coords < off + advance && glyphs[i].end > glyphs[i].start + 1) {
+ int cnt = glyphs[i].end - glyphs[i].start;
+ real_t char_adv = advance / (real_t)(cnt);
+ real_t sub_off = off;
+ for (int j = 0; j < cnt; j++) {
+ // Place caret to the left of clicked sub-grapheme.
+ if (p_coords >= sub_off && p_coords < sub_off + char_adv / 2) {
+ if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
+ return glyphs[i].end - j;
+ } else {
+ return glyphs[i].start + j;
+ }
+ }
+ // Place caret to the right of clicked sub-grapheme.
+ if (p_coords >= sub_off + char_adv / 2 && p_coords < sub_off + char_adv) {
+ if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
+ return glyphs[i].start + (cnt - 1) - j;
+ } else {
+ return glyphs[i].end - (cnt - 1) + j;
+ }
+ }
+ sub_off += char_adv;
+ }
+ }
// Place caret to the left of clicked grapheme.
if (p_coords >= off && p_coords < off + advance / 2) {
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
diff --git a/servers/text_server.h b/servers/text_server.h
index e9c5248866..d5dccc0edb 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -350,6 +350,9 @@ public:
virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) = 0;
virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) = 0;
+ virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) = 0;
+ virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const = 0;
+
virtual Dictionary font_supported_feature_list(RID p_font_rid) const = 0;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const = 0;
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index 03563026c8..aee98f8fee 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -39,8 +39,6 @@
struct BlitToScreen;
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The XR interface is a template class on top of which we build interface to different AR, VR and tracking SDKs.
The idea is that we subclass this class, implement the logic, and then instantiate a singleton of each interface
when Godot starts. These instances do not initialize themselves but register themselves with the AR/VR server.
@@ -138,4 +136,4 @@ VARIANT_ENUM_CAST(XRInterface::Capabilities);
VARIANT_ENUM_CAST(XRInterface::TrackingStatus);
VARIANT_ENUM_CAST(XRInterface::PlayAreaMode);
-#endif // !XR_INTERFACE_H
+#endif // XR_INTERFACE_H
diff --git a/servers/xr/xr_pose.cpp b/servers/xr/xr_pose.cpp
index ab6eb042c9..0862fefef5 100644
--- a/servers/xr/xr_pose.cpp
+++ b/servers/xr/xr_pose.cpp
@@ -35,7 +35,7 @@
void XRPose::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_has_tracking_data", "has_tracking_data"), &XRPose::set_has_tracking_data);
ClassDB::bind_method(D_METHOD("get_has_tracking_data"), &XRPose::get_has_tracking_data);
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "has_tracking_data"), "set_has_tracking_data", "get_has_tracking_data");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "has_tracking_data"), "set_has_tracking_data", "get_has_tracking_data");
ClassDB::bind_method(D_METHOD("set_name", "name"), &XRPose::set_name);
ClassDB::bind_method(D_METHOD("get_name"), &XRPose::get_name);
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index 895bcab215..2bcbf2c018 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -37,8 +37,6 @@
#include "servers/xr_server.h"
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The positional tracker object as an object that represents the position and orientation of a tracked object like a controller or headset.
An AR/VR Interface will registered the trackers it manages with our AR/VR server and update its position and orientation.
This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking.
@@ -99,4 +97,4 @@ public:
VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand);
-#endif
+#endif // XR_POSITIONAL_TRACKER_H
diff --git a/servers/xr_server.h b/servers/xr_server.h
index 824a42ed31..a820634bd9 100644
--- a/servers/xr_server.h
+++ b/servers/xr_server.h
@@ -41,8 +41,6 @@ class XRInterface;
class XRPositionalTracker;
/**
- @author Bastiaan Olij <mux213@gmail.com>
-
The XR server is a singleton object that gives access to the various
objects and SDKs that are available on the system.
Because there can be multiple SDKs active this is exposed as an array
@@ -193,4 +191,4 @@ public:
VARIANT_ENUM_CAST(XRServer::TrackerType);
VARIANT_ENUM_CAST(XRServer::RotationMode);
-#endif
+#endif // XR_SERVER_H
diff --git a/thirdparty/README.md b/thirdparty/README.md
index d3e48bd2bf..239ea940ca 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -175,10 +175,14 @@ Version should be kept in sync with the one of the used Vulkan SDK (see `vulkan`
section). Check Vulkan-ValidationLayers at the matching SDK tag for the known
good glslang commit: https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/scripts/known_good.json
+When updating, also review that our `modules/glslang/glslang_resource_limits.h`
+copy of `DefaultTBuiltInResource` is in sync with the one defined upstream in
+`StandAlone/ResourceLimits.cpp`.
+
Files extracted from upstream source:
-- `glslang` (except `glslang/HLSL`), `OGLCompilersDLL`, `SPIRV`
-- `StandAlone/{DirStackFileIncluder.h,ResourceLimits.{cpp,h}}`
+- `glslang` (except `glslang/HLSL`), `OGLCompilersDLL`, `SPIRV`,
+ minus the `CInterface` folders (depends on `StandAlone`)
- Run `cmake . && make` and copy generated `include/glslang/build_info.h`
to `glslang/build_info.h`
- `LICENSE.txt`
@@ -201,7 +205,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 3.1.2 (8aed5c21a31eece6a9f3cd775fda8facb6c28b9b, 2021)
+- Version: 3.2.0 (be91d2917d9860326cb5fd1d03ffe1042a72f6d3, 2021)
- License: MIT
Files extracted from upstream source:
@@ -325,14 +329,11 @@ changes are marked with `// -- GODOT --` comments.
File extracted from upstream release tarball:
-- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/`.
-- All `*.c` from `library/` to `thirdparty/mbedtls/library/`.
+- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` except `config_psa.h` and `psa_util.h`.
+- All `*.c` and `*.h` from `library/` to `thirdparty/mbedtls/library/` except those starting with `psa_*`.
- `LICENSE` and `apache-2.0.txt` files.
- Applied the patch in `patches/1453.diff` (upstream PR:
https://github.com/ARMmbed/mbedtls/pull/1453).
-- Applied the patch in `patches/padlock.diff`. This disables VIA padlock
- support which defines a symbol `unsupported` which clashes with a
- pre-defined symbol.
- Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
providing configuration for light bundling with core.
diff --git a/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp b/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp
deleted file mode 100644
index a0790f48f1..0000000000
--- a/thirdparty/glslang/SPIRV/CInterface/spirv_c_interface.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- This code is based on the glslang_c_interface implementation by Viktor Latypov
-**/
-
-/**
-BSD 2-Clause License
-
-Copyright (c) 2019, Viktor Latypov
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 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 HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include "glslang/Include/glslang_c_interface.h"
-
-#include "SPIRV/GlslangToSpv.h"
-#include "SPIRV/Logger.h"
-#include "SPIRV/SpvTools.h"
-
-typedef struct glslang_program_s {
- glslang::TProgram* program;
- std::vector<unsigned int> spirv;
- std::string loggerMessages;
-} glslang_program_t;
-
-static EShLanguage c_shader_stage(glslang_stage_t stage)
-{
- switch (stage) {
- case GLSLANG_STAGE_VERTEX:
- return EShLangVertex;
- case GLSLANG_STAGE_TESSCONTROL:
- return EShLangTessControl;
- case GLSLANG_STAGE_TESSEVALUATION:
- return EShLangTessEvaluation;
- case GLSLANG_STAGE_GEOMETRY:
- return EShLangGeometry;
- case GLSLANG_STAGE_FRAGMENT:
- return EShLangFragment;
- case GLSLANG_STAGE_COMPUTE:
- return EShLangCompute;
- case GLSLANG_STAGE_RAYGEN_NV:
- return EShLangRayGen;
- case GLSLANG_STAGE_INTERSECT_NV:
- return EShLangIntersect;
- case GLSLANG_STAGE_ANYHIT_NV:
- return EShLangAnyHit;
- case GLSLANG_STAGE_CLOSESTHIT_NV:
- return EShLangClosestHit;
- case GLSLANG_STAGE_MISS_NV:
- return EShLangMiss;
- case GLSLANG_STAGE_CALLABLE_NV:
- return EShLangCallable;
- case GLSLANG_STAGE_TASK_NV:
- return EShLangTaskNV;
- case GLSLANG_STAGE_MESH_NV:
- return EShLangMeshNV;
- default:
- break;
- }
- return EShLangCount;
-}
-
-GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
-{
- spv::SpvBuildLogger logger;
- glslang::SpvOptions spvOptions;
- spvOptions.validate = true;
-
- const glslang::TIntermediate* intermediate = program->program->getIntermediate(c_shader_stage(stage));
-
- glslang::GlslangToSpv(*intermediate, program->spirv, &logger, &spvOptions);
-
- program->loggerMessages = logger.getAllMessages();
-}
-
-GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program) { return program->spirv.size(); }
-
-GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int* out)
-{
- memcpy(out, program->spirv.data(), program->spirv.size() * sizeof(unsigned int));
-}
-
-GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
-{
- return program->spirv.data();
-}
-
-GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program)
-{
- return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
-}
diff --git a/thirdparty/glslang/StandAlone/DirStackFileIncluder.h b/thirdparty/glslang/StandAlone/DirStackFileIncluder.h
deleted file mode 100644
index 5a33c78fa2..0000000000
--- a/thirdparty/glslang/StandAlone/DirStackFileIncluder.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-// Copyright (C) 2017 Google, Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-
-#pragma once
-
-#include <vector>
-#include <string>
-#include <fstream>
-#include <algorithm>
-#include <set>
-
-#include "./../glslang/Public/ShaderLang.h"
-
-// Default include class for normal include convention of search backward
-// through the stack of active include paths (for nested includes).
-// Can be overridden to customize.
-class DirStackFileIncluder : public glslang::TShader::Includer {
-public:
- DirStackFileIncluder() : externalLocalDirectoryCount(0) { }
-
- virtual IncludeResult* includeLocal(const char* headerName,
- const char* includerName,
- size_t inclusionDepth) override
- {
- return readLocalPath(headerName, includerName, (int)inclusionDepth);
- }
-
- virtual IncludeResult* includeSystem(const char* headerName,
- const char* /*includerName*/,
- size_t /*inclusionDepth*/) override
- {
- return readSystemPath(headerName);
- }
-
- // Externally set directories. E.g., from a command-line -I<dir>.
- // - Most-recently pushed are checked first.
- // - All these are checked after the parse-time stack of local directories
- // is checked.
- // - This only applies to the "local" form of #include.
- // - Makes its own copy of the path.
- virtual void pushExternalLocalDirectory(const std::string& dir)
- {
- directoryStack.push_back(dir);
- externalLocalDirectoryCount = (int)directoryStack.size();
- }
-
- virtual void releaseInclude(IncludeResult* result) override
- {
- if (result != nullptr) {
- delete [] static_cast<tUserDataElement*>(result->userData);
- delete result;
- }
- }
-
- virtual std::set<std::string> getIncludedFiles()
- {
- return includedFiles;
- }
-
- virtual ~DirStackFileIncluder() override { }
-
-protected:
- typedef char tUserDataElement;
- std::vector<std::string> directoryStack;
- int externalLocalDirectoryCount;
- std::set<std::string> includedFiles;
-
- // Search for a valid "local" path based on combining the stack of include
- // directories and the nominal name of the header.
- virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth)
- {
- // Discard popped include directories, and
- // initialize when at parse-time first level.
- directoryStack.resize(depth + externalLocalDirectoryCount);
- if (depth == 1)
- directoryStack.back() = getDirectory(includerName);
-
- // Find a directory that works, using a reverse search of the include stack.
- for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) {
- std::string path = *it + '/' + headerName;
- std::replace(path.begin(), path.end(), '\\', '/');
- std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
- if (file) {
- directoryStack.push_back(getDirectory(path));
- includedFiles.insert(path);
- return newIncludeResult(path, file, (int)file.tellg());
- }
- }
-
- return nullptr;
- }
-
- // Search for a valid <system> path.
- // Not implemented yet; returning nullptr signals failure to find.
- virtual IncludeResult* readSystemPath(const char* /*headerName*/) const
- {
- return nullptr;
- }
-
- // Do actual reading of the file, filling in a new include result.
- virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const
- {
- char* content = new tUserDataElement [length];
- file.seekg(0, file.beg);
- file.read(content, length);
- return new IncludeResult(path, content, length, content);
- }
-
- // If no path markers, return current working directory.
- // Otherwise, strip file name and return path leading up to it.
- virtual std::string getDirectory(const std::string path) const
- {
- size_t last = path.find_last_of("/\\");
- return last == std::string::npos ? "." : path.substr(0, last);
- }
-};
diff --git a/thirdparty/glslang/StandAlone/ResourceLimits.cpp b/thirdparty/glslang/StandAlone/ResourceLimits.cpp
deleted file mode 100644
index 7c7f4c4e49..0000000000
--- a/thirdparty/glslang/StandAlone/ResourceLimits.cpp
+++ /dev/null
@@ -1,496 +0,0 @@
-//
-// Copyright (C) 2016 Google, Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-#include <cstdlib>
-#include <cstring>
-#include <sstream>
-#include <cctype>
-
-#include "ResourceLimits.h"
-
-namespace glslang {
-
-const TBuiltInResource DefaultTBuiltInResource = {
- /* .MaxLights = */ 32,
- /* .MaxClipPlanes = */ 6,
- /* .MaxTextureUnits = */ 32,
- /* .MaxTextureCoords = */ 32,
- /* .MaxVertexAttribs = */ 64,
- /* .MaxVertexUniformComponents = */ 4096,
- /* .MaxVaryingFloats = */ 64,
- /* .MaxVertexTextureImageUnits = */ 32,
- /* .MaxCombinedTextureImageUnits = */ 80,
- /* .MaxTextureImageUnits = */ 32,
- /* .MaxFragmentUniformComponents = */ 4096,
- /* .MaxDrawBuffers = */ 32,
- /* .MaxVertexUniformVectors = */ 128,
- /* .MaxVaryingVectors = */ 8,
- /* .MaxFragmentUniformVectors = */ 16,
- /* .MaxVertexOutputVectors = */ 16,
- /* .MaxFragmentInputVectors = */ 15,
- /* .MinProgramTexelOffset = */ -8,
- /* .MaxProgramTexelOffset = */ 7,
- /* .MaxClipDistances = */ 8,
- /* .MaxComputeWorkGroupCountX = */ 65535,
- /* .MaxComputeWorkGroupCountY = */ 65535,
- /* .MaxComputeWorkGroupCountZ = */ 65535,
- /* .MaxComputeWorkGroupSizeX = */ 1024,
- /* .MaxComputeWorkGroupSizeY = */ 1024,
- /* .MaxComputeWorkGroupSizeZ = */ 64,
- /* .MaxComputeUniformComponents = */ 1024,
- /* .MaxComputeTextureImageUnits = */ 16,
- /* .MaxComputeImageUniforms = */ 8,
- /* .MaxComputeAtomicCounters = */ 8,
- /* .MaxComputeAtomicCounterBuffers = */ 1,
- /* .MaxVaryingComponents = */ 60,
- /* .MaxVertexOutputComponents = */ 64,
- /* .MaxGeometryInputComponents = */ 64,
- /* .MaxGeometryOutputComponents = */ 128,
- /* .MaxFragmentInputComponents = */ 128,
- /* .MaxImageUnits = */ 8,
- /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
- /* .MaxCombinedShaderOutputResources = */ 8,
- /* .MaxImageSamples = */ 0,
- /* .MaxVertexImageUniforms = */ 0,
- /* .MaxTessControlImageUniforms = */ 0,
- /* .MaxTessEvaluationImageUniforms = */ 0,
- /* .MaxGeometryImageUniforms = */ 0,
- /* .MaxFragmentImageUniforms = */ 8,
- /* .MaxCombinedImageUniforms = */ 8,
- /* .MaxGeometryTextureImageUnits = */ 16,
- /* .MaxGeometryOutputVertices = */ 256,
- /* .MaxGeometryTotalOutputComponents = */ 1024,
- /* .MaxGeometryUniformComponents = */ 1024,
- /* .MaxGeometryVaryingComponents = */ 64,
- /* .MaxTessControlInputComponents = */ 128,
- /* .MaxTessControlOutputComponents = */ 128,
- /* .MaxTessControlTextureImageUnits = */ 16,
- /* .MaxTessControlUniformComponents = */ 1024,
- /* .MaxTessControlTotalOutputComponents = */ 4096,
- /* .MaxTessEvaluationInputComponents = */ 128,
- /* .MaxTessEvaluationOutputComponents = */ 128,
- /* .MaxTessEvaluationTextureImageUnits = */ 16,
- /* .MaxTessEvaluationUniformComponents = */ 1024,
- /* .MaxTessPatchComponents = */ 120,
- /* .MaxPatchVertices = */ 32,
- /* .MaxTessGenLevel = */ 64,
- /* .MaxViewports = */ 16,
- /* .MaxVertexAtomicCounters = */ 0,
- /* .MaxTessControlAtomicCounters = */ 0,
- /* .MaxTessEvaluationAtomicCounters = */ 0,
- /* .MaxGeometryAtomicCounters = */ 0,
- /* .MaxFragmentAtomicCounters = */ 8,
- /* .MaxCombinedAtomicCounters = */ 8,
- /* .MaxAtomicCounterBindings = */ 1,
- /* .MaxVertexAtomicCounterBuffers = */ 0,
- /* .MaxTessControlAtomicCounterBuffers = */ 0,
- /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
- /* .MaxGeometryAtomicCounterBuffers = */ 0,
- /* .MaxFragmentAtomicCounterBuffers = */ 1,
- /* .MaxCombinedAtomicCounterBuffers = */ 1,
- /* .MaxAtomicCounterBufferSize = */ 16384,
- /* .MaxTransformFeedbackBuffers = */ 4,
- /* .MaxTransformFeedbackInterleavedComponents = */ 64,
- /* .MaxCullDistances = */ 8,
- /* .MaxCombinedClipAndCullDistances = */ 8,
- /* .MaxSamples = */ 4,
- /* .maxMeshOutputVerticesNV = */ 256,
- /* .maxMeshOutputPrimitivesNV = */ 512,
- /* .maxMeshWorkGroupSizeX_NV = */ 32,
- /* .maxMeshWorkGroupSizeY_NV = */ 1,
- /* .maxMeshWorkGroupSizeZ_NV = */ 1,
- /* .maxTaskWorkGroupSizeX_NV = */ 32,
- /* .maxTaskWorkGroupSizeY_NV = */ 1,
- /* .maxTaskWorkGroupSizeZ_NV = */ 1,
- /* .maxMeshViewCountNV = */ 4,
- /* .maxDualSourceDrawBuffersEXT = */ 1,
-
- /* .limits = */ {
- /* .nonInductiveForLoops = */ 1,
- /* .whileLoops = */ 1,
- /* .doWhileLoops = */ 1,
- /* .generalUniformIndexing = */ 1,
- /* .generalAttributeMatrixVectorIndexing = */ 1,
- /* .generalVaryingIndexing = */ 1,
- /* .generalSamplerIndexing = */ 1,
- /* .generalVariableIndexing = */ 1,
- /* .generalConstantMatrixVectorIndexing = */ 1,
- }};
-
-std::string GetDefaultTBuiltInResourceString()
-{
- std::ostringstream ostream;
-
- ostream << "MaxLights " << DefaultTBuiltInResource.maxLights << "\n"
- << "MaxClipPlanes " << DefaultTBuiltInResource.maxClipPlanes << "\n"
- << "MaxTextureUnits " << DefaultTBuiltInResource.maxTextureUnits << "\n"
- << "MaxTextureCoords " << DefaultTBuiltInResource.maxTextureCoords << "\n"
- << "MaxVertexAttribs " << DefaultTBuiltInResource.maxVertexAttribs << "\n"
- << "MaxVertexUniformComponents " << DefaultTBuiltInResource.maxVertexUniformComponents << "\n"
- << "MaxVaryingFloats " << DefaultTBuiltInResource.maxVaryingFloats << "\n"
- << "MaxVertexTextureImageUnits " << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n"
- << "MaxCombinedTextureImageUnits " << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n"
- << "MaxTextureImageUnits " << DefaultTBuiltInResource.maxTextureImageUnits << "\n"
- << "MaxFragmentUniformComponents " << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n"
- << "MaxDrawBuffers " << DefaultTBuiltInResource.maxDrawBuffers << "\n"
- << "MaxVertexUniformVectors " << DefaultTBuiltInResource.maxVertexUniformVectors << "\n"
- << "MaxVaryingVectors " << DefaultTBuiltInResource.maxVaryingVectors << "\n"
- << "MaxFragmentUniformVectors " << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n"
- << "MaxVertexOutputVectors " << DefaultTBuiltInResource.maxVertexOutputVectors << "\n"
- << "MaxFragmentInputVectors " << DefaultTBuiltInResource.maxFragmentInputVectors << "\n"
- << "MinProgramTexelOffset " << DefaultTBuiltInResource.minProgramTexelOffset << "\n"
- << "MaxProgramTexelOffset " << DefaultTBuiltInResource.maxProgramTexelOffset << "\n"
- << "MaxClipDistances " << DefaultTBuiltInResource.maxClipDistances << "\n"
- << "MaxComputeWorkGroupCountX " << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n"
- << "MaxComputeWorkGroupCountY " << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n"
- << "MaxComputeWorkGroupCountZ " << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n"
- << "MaxComputeWorkGroupSizeX " << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n"
- << "MaxComputeWorkGroupSizeY " << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n"
- << "MaxComputeWorkGroupSizeZ " << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n"
- << "MaxComputeUniformComponents " << DefaultTBuiltInResource.maxComputeUniformComponents << "\n"
- << "MaxComputeTextureImageUnits " << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n"
- << "MaxComputeImageUniforms " << DefaultTBuiltInResource.maxComputeImageUniforms << "\n"
- << "MaxComputeAtomicCounters " << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n"
- << "MaxComputeAtomicCounterBuffers " << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n"
- << "MaxVaryingComponents " << DefaultTBuiltInResource.maxVaryingComponents << "\n"
- << "MaxVertexOutputComponents " << DefaultTBuiltInResource.maxVertexOutputComponents << "\n"
- << "MaxGeometryInputComponents " << DefaultTBuiltInResource.maxGeometryInputComponents << "\n"
- << "MaxGeometryOutputComponents " << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n"
- << "MaxFragmentInputComponents " << DefaultTBuiltInResource.maxFragmentInputComponents << "\n"
- << "MaxImageUnits " << DefaultTBuiltInResource.maxImageUnits << "\n"
- << "MaxCombinedImageUnitsAndFragmentOutputs " << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n"
- << "MaxCombinedShaderOutputResources " << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n"
- << "MaxImageSamples " << DefaultTBuiltInResource.maxImageSamples << "\n"
- << "MaxVertexImageUniforms " << DefaultTBuiltInResource.maxVertexImageUniforms << "\n"
- << "MaxTessControlImageUniforms " << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n"
- << "MaxTessEvaluationImageUniforms " << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n"
- << "MaxGeometryImageUniforms " << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n"
- << "MaxFragmentImageUniforms " << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n"
- << "MaxCombinedImageUniforms " << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n"
- << "MaxGeometryTextureImageUnits " << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n"
- << "MaxGeometryOutputVertices " << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n"
- << "MaxGeometryTotalOutputComponents " << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n"
- << "MaxGeometryUniformComponents " << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n"
- << "MaxGeometryVaryingComponents " << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n"
- << "MaxTessControlInputComponents " << DefaultTBuiltInResource.maxTessControlInputComponents << "\n"
- << "MaxTessControlOutputComponents " << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n"
- << "MaxTessControlTextureImageUnits " << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n"
- << "MaxTessControlUniformComponents " << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n"
- << "MaxTessControlTotalOutputComponents " << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n"
- << "MaxTessEvaluationInputComponents " << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n"
- << "MaxTessEvaluationOutputComponents " << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n"
- << "MaxTessEvaluationTextureImageUnits " << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n"
- << "MaxTessEvaluationUniformComponents " << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n"
- << "MaxTessPatchComponents " << DefaultTBuiltInResource.maxTessPatchComponents << "\n"
- << "MaxPatchVertices " << DefaultTBuiltInResource.maxPatchVertices << "\n"
- << "MaxTessGenLevel " << DefaultTBuiltInResource.maxTessGenLevel << "\n"
- << "MaxViewports " << DefaultTBuiltInResource.maxViewports << "\n"
- << "MaxVertexAtomicCounters " << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n"
- << "MaxTessControlAtomicCounters " << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n"
- << "MaxTessEvaluationAtomicCounters " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n"
- << "MaxGeometryAtomicCounters " << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n"
- << "MaxFragmentAtomicCounters " << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n"
- << "MaxCombinedAtomicCounters " << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n"
- << "MaxAtomicCounterBindings " << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n"
- << "MaxVertexAtomicCounterBuffers " << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n"
- << "MaxTessControlAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n"
- << "MaxTessEvaluationAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n"
- << "MaxGeometryAtomicCounterBuffers " << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n"
- << "MaxFragmentAtomicCounterBuffers " << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n"
- << "MaxCombinedAtomicCounterBuffers " << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n"
- << "MaxAtomicCounterBufferSize " << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n"
- << "MaxTransformFeedbackBuffers " << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n"
- << "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n"
- << "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n"
- << "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n"
- << "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n"
- << "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n"
- << "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n"
- << "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n"
- << "MaxMeshWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_NV << "\n"
- << "MaxMeshWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_NV << "\n"
- << "MaxTaskWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_NV << "\n"
- << "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n"
- << "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n"
- << "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n"
- << "MaxDualSourceDrawBuffersEXT " << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n"
- << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
- << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n"
- << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
- << "generalUniformIndexing " << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n"
- << "generalAttributeMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n"
- << "generalVaryingIndexing " << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n"
- << "generalSamplerIndexing " << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n"
- << "generalVariableIndexing " << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n"
- << "generalConstantMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n"
- ;
-
- return ostream.str();
-}
-
-void DecodeResourceLimits(TBuiltInResource* resources, char* config)
-{
- static const char* delims = " \t\n\r";
-
- size_t pos = 0;
- std::string configStr(config);
-
- while ((pos = configStr.find_first_not_of(delims, pos)) != std::string::npos) {
- const size_t token_s = pos;
- const size_t token_e = configStr.find_first_of(delims, token_s);
- const size_t value_s = configStr.find_first_not_of(delims, token_e);
- const size_t value_e = configStr.find_first_of(delims, value_s);
- pos = value_e;
-
- // Faster to use compare(), but prefering readability.
- const std::string tokenStr = configStr.substr(token_s, token_e-token_s);
- const std::string valueStr = configStr.substr(value_s, value_e-value_s);
-
- if (value_s == std::string::npos || ! (valueStr[0] == '-' || isdigit(valueStr[0]))) {
- printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n",
- valueStr.c_str());
- return;
- }
-
- const int value = std::atoi(valueStr.c_str());
-
- if (tokenStr == "MaxLights")
- resources->maxLights = value;
- else if (tokenStr == "MaxClipPlanes")
- resources->maxClipPlanes = value;
- else if (tokenStr == "MaxTextureUnits")
- resources->maxTextureUnits = value;
- else if (tokenStr == "MaxTextureCoords")
- resources->maxTextureCoords = value;
- else if (tokenStr == "MaxVertexAttribs")
- resources->maxVertexAttribs = value;
- else if (tokenStr == "MaxVertexUniformComponents")
- resources->maxVertexUniformComponents = value;
- else if (tokenStr == "MaxVaryingFloats")
- resources->maxVaryingFloats = value;
- else if (tokenStr == "MaxVertexTextureImageUnits")
- resources->maxVertexTextureImageUnits = value;
- else if (tokenStr == "MaxCombinedTextureImageUnits")
- resources->maxCombinedTextureImageUnits = value;
- else if (tokenStr == "MaxTextureImageUnits")
- resources->maxTextureImageUnits = value;
- else if (tokenStr == "MaxFragmentUniformComponents")
- resources->maxFragmentUniformComponents = value;
- else if (tokenStr == "MaxDrawBuffers")
- resources->maxDrawBuffers = value;
- else if (tokenStr == "MaxVertexUniformVectors")
- resources->maxVertexUniformVectors = value;
- else if (tokenStr == "MaxVaryingVectors")
- resources->maxVaryingVectors = value;
- else if (tokenStr == "MaxFragmentUniformVectors")
- resources->maxFragmentUniformVectors = value;
- else if (tokenStr == "MaxVertexOutputVectors")
- resources->maxVertexOutputVectors = value;
- else if (tokenStr == "MaxFragmentInputVectors")
- resources->maxFragmentInputVectors = value;
- else if (tokenStr == "MinProgramTexelOffset")
- resources->minProgramTexelOffset = value;
- else if (tokenStr == "MaxProgramTexelOffset")
- resources->maxProgramTexelOffset = value;
- else if (tokenStr == "MaxClipDistances")
- resources->maxClipDistances = value;
- else if (tokenStr == "MaxComputeWorkGroupCountX")
- resources->maxComputeWorkGroupCountX = value;
- else if (tokenStr == "MaxComputeWorkGroupCountY")
- resources->maxComputeWorkGroupCountY = value;
- else if (tokenStr == "MaxComputeWorkGroupCountZ")
- resources->maxComputeWorkGroupCountZ = value;
- else if (tokenStr == "MaxComputeWorkGroupSizeX")
- resources->maxComputeWorkGroupSizeX = value;
- else if (tokenStr == "MaxComputeWorkGroupSizeY")
- resources->maxComputeWorkGroupSizeY = value;
- else if (tokenStr == "MaxComputeWorkGroupSizeZ")
- resources->maxComputeWorkGroupSizeZ = value;
- else if (tokenStr == "MaxComputeUniformComponents")
- resources->maxComputeUniformComponents = value;
- else if (tokenStr == "MaxComputeTextureImageUnits")
- resources->maxComputeTextureImageUnits = value;
- else if (tokenStr == "MaxComputeImageUniforms")
- resources->maxComputeImageUniforms = value;
- else if (tokenStr == "MaxComputeAtomicCounters")
- resources->maxComputeAtomicCounters = value;
- else if (tokenStr == "MaxComputeAtomicCounterBuffers")
- resources->maxComputeAtomicCounterBuffers = value;
- else if (tokenStr == "MaxVaryingComponents")
- resources->maxVaryingComponents = value;
- else if (tokenStr == "MaxVertexOutputComponents")
- resources->maxVertexOutputComponents = value;
- else if (tokenStr == "MaxGeometryInputComponents")
- resources->maxGeometryInputComponents = value;
- else if (tokenStr == "MaxGeometryOutputComponents")
- resources->maxGeometryOutputComponents = value;
- else if (tokenStr == "MaxFragmentInputComponents")
- resources->maxFragmentInputComponents = value;
- else if (tokenStr == "MaxImageUnits")
- resources->maxImageUnits = value;
- else if (tokenStr == "MaxCombinedImageUnitsAndFragmentOutputs")
- resources->maxCombinedImageUnitsAndFragmentOutputs = value;
- else if (tokenStr == "MaxCombinedShaderOutputResources")
- resources->maxCombinedShaderOutputResources = value;
- else if (tokenStr == "MaxImageSamples")
- resources->maxImageSamples = value;
- else if (tokenStr == "MaxVertexImageUniforms")
- resources->maxVertexImageUniforms = value;
- else if (tokenStr == "MaxTessControlImageUniforms")
- resources->maxTessControlImageUniforms = value;
- else if (tokenStr == "MaxTessEvaluationImageUniforms")
- resources->maxTessEvaluationImageUniforms = value;
- else if (tokenStr == "MaxGeometryImageUniforms")
- resources->maxGeometryImageUniforms = value;
- else if (tokenStr == "MaxFragmentImageUniforms")
- resources->maxFragmentImageUniforms = value;
- else if (tokenStr == "MaxCombinedImageUniforms")
- resources->maxCombinedImageUniforms = value;
- else if (tokenStr == "MaxGeometryTextureImageUnits")
- resources->maxGeometryTextureImageUnits = value;
- else if (tokenStr == "MaxGeometryOutputVertices")
- resources->maxGeometryOutputVertices = value;
- else if (tokenStr == "MaxGeometryTotalOutputComponents")
- resources->maxGeometryTotalOutputComponents = value;
- else if (tokenStr == "MaxGeometryUniformComponents")
- resources->maxGeometryUniformComponents = value;
- else if (tokenStr == "MaxGeometryVaryingComponents")
- resources->maxGeometryVaryingComponents = value;
- else if (tokenStr == "MaxTessControlInputComponents")
- resources->maxTessControlInputComponents = value;
- else if (tokenStr == "MaxTessControlOutputComponents")
- resources->maxTessControlOutputComponents = value;
- else if (tokenStr == "MaxTessControlTextureImageUnits")
- resources->maxTessControlTextureImageUnits = value;
- else if (tokenStr == "MaxTessControlUniformComponents")
- resources->maxTessControlUniformComponents = value;
- else if (tokenStr == "MaxTessControlTotalOutputComponents")
- resources->maxTessControlTotalOutputComponents = value;
- else if (tokenStr == "MaxTessEvaluationInputComponents")
- resources->maxTessEvaluationInputComponents = value;
- else if (tokenStr == "MaxTessEvaluationOutputComponents")
- resources->maxTessEvaluationOutputComponents = value;
- else if (tokenStr == "MaxTessEvaluationTextureImageUnits")
- resources->maxTessEvaluationTextureImageUnits = value;
- else if (tokenStr == "MaxTessEvaluationUniformComponents")
- resources->maxTessEvaluationUniformComponents = value;
- else if (tokenStr == "MaxTessPatchComponents")
- resources->maxTessPatchComponents = value;
- else if (tokenStr == "MaxPatchVertices")
- resources->maxPatchVertices = value;
- else if (tokenStr == "MaxTessGenLevel")
- resources->maxTessGenLevel = value;
- else if (tokenStr == "MaxViewports")
- resources->maxViewports = value;
- else if (tokenStr == "MaxVertexAtomicCounters")
- resources->maxVertexAtomicCounters = value;
- else if (tokenStr == "MaxTessControlAtomicCounters")
- resources->maxTessControlAtomicCounters = value;
- else if (tokenStr == "MaxTessEvaluationAtomicCounters")
- resources->maxTessEvaluationAtomicCounters = value;
- else if (tokenStr == "MaxGeometryAtomicCounters")
- resources->maxGeometryAtomicCounters = value;
- else if (tokenStr == "MaxFragmentAtomicCounters")
- resources->maxFragmentAtomicCounters = value;
- else if (tokenStr == "MaxCombinedAtomicCounters")
- resources->maxCombinedAtomicCounters = value;
- else if (tokenStr == "MaxAtomicCounterBindings")
- resources->maxAtomicCounterBindings = value;
- else if (tokenStr == "MaxVertexAtomicCounterBuffers")
- resources->maxVertexAtomicCounterBuffers = value;
- else if (tokenStr == "MaxTessControlAtomicCounterBuffers")
- resources->maxTessControlAtomicCounterBuffers = value;
- else if (tokenStr == "MaxTessEvaluationAtomicCounterBuffers")
- resources->maxTessEvaluationAtomicCounterBuffers = value;
- else if (tokenStr == "MaxGeometryAtomicCounterBuffers")
- resources->maxGeometryAtomicCounterBuffers = value;
- else if (tokenStr == "MaxFragmentAtomicCounterBuffers")
- resources->maxFragmentAtomicCounterBuffers = value;
- else if (tokenStr == "MaxCombinedAtomicCounterBuffers")
- resources->maxCombinedAtomicCounterBuffers = value;
- else if (tokenStr == "MaxAtomicCounterBufferSize")
- resources->maxAtomicCounterBufferSize = value;
- else if (tokenStr == "MaxTransformFeedbackBuffers")
- resources->maxTransformFeedbackBuffers = value;
- else if (tokenStr == "MaxTransformFeedbackInterleavedComponents")
- resources->maxTransformFeedbackInterleavedComponents = value;
- else if (tokenStr == "MaxCullDistances")
- resources->maxCullDistances = value;
- else if (tokenStr == "MaxCombinedClipAndCullDistances")
- resources->maxCombinedClipAndCullDistances = value;
- else if (tokenStr == "MaxSamples")
- resources->maxSamples = value;
- else if (tokenStr == "MaxMeshOutputVerticesNV")
- resources->maxMeshOutputVerticesNV = value;
- else if (tokenStr == "MaxMeshOutputPrimitivesNV")
- resources->maxMeshOutputPrimitivesNV = value;
- else if (tokenStr == "MaxMeshWorkGroupSizeX_NV")
- resources->maxMeshWorkGroupSizeX_NV = value;
- else if (tokenStr == "MaxMeshWorkGroupSizeY_NV")
- resources->maxMeshWorkGroupSizeY_NV = value;
- else if (tokenStr == "MaxMeshWorkGroupSizeZ_NV")
- resources->maxMeshWorkGroupSizeZ_NV = value;
- else if (tokenStr == "MaxTaskWorkGroupSizeX_NV")
- resources->maxTaskWorkGroupSizeX_NV = value;
- else if (tokenStr == "MaxTaskWorkGroupSizeY_NV")
- resources->maxTaskWorkGroupSizeY_NV = value;
- else if (tokenStr == "MaxTaskWorkGroupSizeZ_NV")
- resources->maxTaskWorkGroupSizeZ_NV = value;
- else if (tokenStr == "MaxMeshViewCountNV")
- resources->maxMeshViewCountNV = value;
- else if (tokenStr == "nonInductiveForLoops")
- resources->limits.nonInductiveForLoops = (value != 0);
- else if (tokenStr == "whileLoops")
- resources->limits.whileLoops = (value != 0);
- else if (tokenStr == "doWhileLoops")
- resources->limits.doWhileLoops = (value != 0);
- else if (tokenStr == "generalUniformIndexing")
- resources->limits.generalUniformIndexing = (value != 0);
- else if (tokenStr == "generalAttributeMatrixVectorIndexing")
- resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
- else if (tokenStr == "generalVaryingIndexing")
- resources->limits.generalVaryingIndexing = (value != 0);
- else if (tokenStr == "generalSamplerIndexing")
- resources->limits.generalSamplerIndexing = (value != 0);
- else if (tokenStr == "generalVariableIndexing")
- resources->limits.generalVariableIndexing = (value != 0);
- else if (tokenStr == "generalConstantMatrixVectorIndexing")
- resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
- else
- printf("Warning: unrecognized limit (%s) in configuration file.\n", tokenStr.c_str());
-
- }
-}
-
-} // end namespace glslang
diff --git a/thirdparty/glslang/StandAlone/ResourceLimits.h b/thirdparty/glslang/StandAlone/ResourceLimits.h
deleted file mode 100644
index 736248eb39..0000000000
--- a/thirdparty/glslang/StandAlone/ResourceLimits.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright (C) 2016 Google, Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
-#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
-
-#include <string>
-
-#include "../glslang/Include/ResourceLimits.h"
-
-namespace glslang {
-
-// These are the default resources for TBuiltInResources, used for both
-// - parsing this string for the case where the user didn't supply one,
-// - dumping out a template for user construction of a config file.
-extern const TBuiltInResource DefaultTBuiltInResource;
-
-// Returns the DefaultTBuiltInResource as a human-readable string.
-std::string GetDefaultTBuiltInResourceString();
-
-// Decodes the resource limits from |config| to |resources|.
-void DecodeResourceLimits(TBuiltInResource* resources, char* config);
-
-} // end namespace glslang
-
-#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
diff --git a/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp b/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp
deleted file mode 100644
index 2e04f53ace..0000000000
--- a/thirdparty/glslang/glslang/CInterface/glslang_c_interface.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/**
- This code is based on the glslang_c_interface implementation by Viktor Latypov
-**/
-
-/**
-BSD 2-Clause License
-
-Copyright (c) 2019, Viktor Latypov
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 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 HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**/
-
-#include "glslang/Include/glslang_c_interface.h"
-
-#include "StandAlone/DirStackFileIncluder.h"
-#include "StandAlone/ResourceLimits.h"
-#include "glslang/Include/ShHandle.h"
-
-#include "glslang/Include/ResourceLimits.h"
-#include "glslang/MachineIndependent/Versions.h"
-
-static_assert(int(GLSLANG_STAGE_COUNT) == EShLangCount, "");
-static_assert(int(GLSLANG_STAGE_MASK_COUNT) == EShLanguageMaskCount, "");
-static_assert(int(GLSLANG_SOURCE_COUNT) == glslang::EShSourceCount, "");
-static_assert(int(GLSLANG_CLIENT_COUNT) == glslang::EShClientCount, "");
-static_assert(int(GLSLANG_TARGET_COUNT) == glslang::EShTargetCount, "");
-static_assert(int(GLSLANG_TARGET_CLIENT_VERSION_COUNT) == glslang::EShTargetClientVersionCount, "");
-static_assert(int(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT) == glslang::EShTargetLanguageVersionCount, "");
-static_assert(int(GLSLANG_OPT_LEVEL_COUNT) == EshOptLevelCount, "");
-static_assert(int(GLSLANG_TEX_SAMP_TRANS_COUNT) == EShTexSampTransCount, "");
-static_assert(int(GLSLANG_MSG_COUNT) == EShMsgCount, "");
-static_assert(int(GLSLANG_REFLECTION_COUNT) == EShReflectionCount, "");
-static_assert(int(GLSLANG_PROFILE_COUNT) == EProfileCount, "");
-static_assert(sizeof(glslang_limits_t) == sizeof(TLimits), "");
-static_assert(sizeof(glslang_resource_t) == sizeof(TBuiltInResource), "");
-
-typedef struct glslang_shader_s {
- glslang::TShader* shader;
- std::string preprocessedGLSL;
-} glslang_shader_t;
-
-typedef struct glslang_program_s {
- glslang::TProgram* program;
- std::vector<unsigned int> spirv;
- std::string loggerMessages;
-} glslang_program_t;
-
-/* Wrapper/Adapter for C glsl_include_callbacks_t functions
-
- This class contains a 'glsl_include_callbacks_t' structure
- with C include_local/include_system callback pointers.
-
- This class implement TShader::Includer interface
- by redirecting C++ virtual methods to C callbacks.
-
- The 'IncludeResult' instances produced by this Includer
- contain a reference to glsl_include_result_t C structure
- to allow its lifetime management by another C callback
- (CallbackIncluder::callbacks::free_include_result)
-*/
-class CallbackIncluder : public glslang::TShader::Includer {
-public:
- /* Wrapper of IncludeResult which stores a glsl_include_result object internally */
- class CallbackIncludeResult : public glslang::TShader::Includer::IncludeResult {
- public:
- CallbackIncludeResult(const std::string& headerName, const char* const headerData, const size_t headerLength,
- void* userData, glsl_include_result_t* includeResult)
- : glslang::TShader::Includer::IncludeResult(headerName, headerData, headerLength, userData),
- includeResult(includeResult)
- {
- }
-
- virtual ~CallbackIncludeResult() {}
-
- protected:
- friend class CallbackIncluder;
-
- glsl_include_result_t* includeResult;
- };
-
-public:
- CallbackIncluder(glsl_include_callbacks_t _callbacks, void* _context) : callbacks(_callbacks), context(_context) {}
-
- virtual ~CallbackIncluder() {}
-
- virtual IncludeResult* includeSystem(const char* headerName, const char* includerName,
- size_t inclusionDepth) override
- {
- if (this->callbacks.include_system) {
- glsl_include_result_t* result =
- this->callbacks.include_system(this->context, headerName, includerName, inclusionDepth);
-
- return new CallbackIncludeResult(std::string(headerName), result->header_data, result->header_length,
- nullptr, result);
- }
-
- return glslang::TShader::Includer::includeSystem(headerName, includerName, inclusionDepth);
- }
-
- virtual IncludeResult* includeLocal(const char* headerName, const char* includerName,
- size_t inclusionDepth) override
- {
- if (this->callbacks.include_local) {
- glsl_include_result_t* result =
- this->callbacks.include_local(this->context, headerName, includerName, inclusionDepth);
-
- return new CallbackIncludeResult(std::string(headerName), result->header_data, result->header_length,
- nullptr, result);
- }
-
- return glslang::TShader::Includer::includeLocal(headerName, includerName, inclusionDepth);
- }
-
- /* This function only calls free_include_result callback
- when the IncludeResult instance is allocated by a C function */
- virtual void releaseInclude(IncludeResult* result) override
- {
- if (result == nullptr)
- return;
-
- if (this->callbacks.free_include_result && (result->userData == nullptr)) {
- CallbackIncludeResult* innerResult = static_cast<CallbackIncludeResult*>(result);
- /* use internal free() function */
- this->callbacks.free_include_result(this->context, innerResult->includeResult);
- /* ignore internal fields of TShader::Includer::IncludeResult */
- delete result;
- return;
- }
-
- delete[] static_cast<char*>(result->userData);
- delete result;
- }
-
-private:
- CallbackIncluder() {}
-
- /* C callback pointers */
- glsl_include_callbacks_t callbacks;
- /* User-defined context */
- void* context;
-};
-
-GLSLANG_EXPORT int glslang_initialize_process() { return static_cast<int>(glslang::InitializeProcess()); }
-
-GLSLANG_EXPORT void glslang_finalize_process() { glslang::FinalizeProcess(); }
-
-static EShLanguage c_shader_stage(glslang_stage_t stage)
-{
- switch (stage) {
- case GLSLANG_STAGE_VERTEX:
- return EShLangVertex;
- case GLSLANG_STAGE_TESSCONTROL:
- return EShLangTessControl;
- case GLSLANG_STAGE_TESSEVALUATION:
- return EShLangTessEvaluation;
- case GLSLANG_STAGE_GEOMETRY:
- return EShLangGeometry;
- case GLSLANG_STAGE_FRAGMENT:
- return EShLangFragment;
- case GLSLANG_STAGE_COMPUTE:
- return EShLangCompute;
- case GLSLANG_STAGE_RAYGEN_NV:
- return EShLangRayGen;
- case GLSLANG_STAGE_INTERSECT_NV:
- return EShLangIntersect;
- case GLSLANG_STAGE_ANYHIT_NV:
- return EShLangAnyHit;
- case GLSLANG_STAGE_CLOSESTHIT_NV:
- return EShLangClosestHit;
- case GLSLANG_STAGE_MISS_NV:
- return EShLangMiss;
- case GLSLANG_STAGE_CALLABLE_NV:
- return EShLangCallable;
- case GLSLANG_STAGE_TASK_NV:
- return EShLangTaskNV;
- case GLSLANG_STAGE_MESH_NV:
- return EShLangMeshNV;
- default:
- break;
- }
- return EShLangCount;
-}
-
-static int c_shader_messages(glslang_messages_t messages)
-{
-#define CONVERT_MSG(in, out) \
- if ((messages & in) == in) \
- res |= out;
-
- int res = 0;
-
- CONVERT_MSG(GLSLANG_MSG_RELAXED_ERRORS_BIT, EShMsgRelaxedErrors);
- CONVERT_MSG(GLSLANG_MSG_SUPPRESS_WARNINGS_BIT, EShMsgSuppressWarnings);
- CONVERT_MSG(GLSLANG_MSG_AST_BIT, EShMsgAST);
- CONVERT_MSG(GLSLANG_MSG_SPV_RULES_BIT, EShMsgSpvRules);
- CONVERT_MSG(GLSLANG_MSG_VULKAN_RULES_BIT, EShMsgVulkanRules);
- CONVERT_MSG(GLSLANG_MSG_ONLY_PREPROCESSOR_BIT, EShMsgOnlyPreprocessor);
- CONVERT_MSG(GLSLANG_MSG_READ_HLSL_BIT, EShMsgReadHlsl);
- CONVERT_MSG(GLSLANG_MSG_CASCADING_ERRORS_BIT, EShMsgCascadingErrors);
- CONVERT_MSG(GLSLANG_MSG_KEEP_UNCALLED_BIT, EShMsgKeepUncalled);
- CONVERT_MSG(GLSLANG_MSG_HLSL_OFFSETS_BIT, EShMsgHlslOffsets);
- CONVERT_MSG(GLSLANG_MSG_DEBUG_INFO_BIT, EShMsgDebugInfo);
- CONVERT_MSG(GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT, EShMsgHlslEnable16BitTypes);
- CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization);
- CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible);
- CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable);
- return res;
-#undef CONVERT_MSG
-}
-
-static glslang::EShTargetLanguageVersion
-c_shader_target_language_version(glslang_target_language_version_t target_language_version)
-{
- switch (target_language_version) {
- case GLSLANG_TARGET_SPV_1_0:
- return glslang::EShTargetSpv_1_0;
- case GLSLANG_TARGET_SPV_1_1:
- return glslang::EShTargetSpv_1_1;
- case GLSLANG_TARGET_SPV_1_2:
- return glslang::EShTargetSpv_1_2;
- case GLSLANG_TARGET_SPV_1_3:
- return glslang::EShTargetSpv_1_3;
- case GLSLANG_TARGET_SPV_1_4:
- return glslang::EShTargetSpv_1_4;
- case GLSLANG_TARGET_SPV_1_5:
- return glslang::EShTargetSpv_1_5;
- default:
- break;
- }
- return glslang::EShTargetSpv_1_0;
-}
-
-static glslang::EShClient c_shader_client(glslang_client_t client)
-{
- switch (client) {
- case GLSLANG_CLIENT_VULKAN:
- return glslang::EShClientVulkan;
- case GLSLANG_CLIENT_OPENGL:
- return glslang::EShClientOpenGL;
- default:
- break;
- }
-
- return glslang::EShClientNone;
-}
-
-static glslang::EShTargetClientVersion c_shader_client_version(glslang_target_client_version_t client_version)
-{
- switch (client_version) {
- case GLSLANG_TARGET_VULKAN_1_1:
- return glslang::EShTargetVulkan_1_1;
- case GLSLANG_TARGET_OPENGL_450:
- return glslang::EShTargetOpenGL_450;
- default:
- break;
- }
-
- return glslang::EShTargetVulkan_1_0;
-}
-
-static glslang::EShTargetLanguage c_shader_target_language(glslang_target_language_t target_language)
-{
- if (target_language == GLSLANG_TARGET_NONE)
- return glslang::EShTargetNone;
-
- return glslang::EShTargetSpv;
-}
-
-static glslang::EShSource c_shader_source(glslang_source_t source)
-{
- switch (source) {
- case GLSLANG_SOURCE_GLSL:
- return glslang::EShSourceGlsl;
- case GLSLANG_SOURCE_HLSL:
- return glslang::EShSourceHlsl;
- default:
- break;
- }
-
- return glslang::EShSourceNone;
-}
-
-static EProfile c_shader_profile(glslang_profile_t profile)
-{
- switch (profile) {
- case GLSLANG_BAD_PROFILE:
- return EBadProfile;
- case GLSLANG_NO_PROFILE:
- return ENoProfile;
- case GLSLANG_CORE_PROFILE:
- return ECoreProfile;
- case GLSLANG_COMPATIBILITY_PROFILE:
- return ECompatibilityProfile;
- case GLSLANG_ES_PROFILE:
- return EEsProfile;
- case GLSLANG_PROFILE_COUNT: // Should not use this
- break;
- }
-
- return EProfile();
-}
-
-GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input)
-{
- if (!input || !input->code) {
- printf("Error creating shader: null input(%p)/input->code\n", input);
-
- if (input)
- printf("input->code = %p\n", input->code);
-
- return nullptr;
- }
-
- glslang_shader_t* shader = new glslang_shader_t();
-
- shader->shader = new glslang::TShader(c_shader_stage(input->stage));
- shader->shader->setStrings(&input->code, 1);
- shader->shader->setEnvInput(c_shader_source(input->language), c_shader_stage(input->stage),
- c_shader_client(input->client), input->default_version);
- shader->shader->setEnvClient(c_shader_client(input->client), c_shader_client_version(input->client_version));
- shader->shader->setEnvTarget(c_shader_target_language(input->target_language),
- c_shader_target_language_version(input->target_language_version));
-
- return shader;
-}
-
-GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
-{
- return shader->preprocessedGLSL.c_str();
-}
-
-GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input)
-{
- DirStackFileIncluder Includer;
- /* TODO: use custom callbacks if they are available in 'i->callbacks' */
- return shader->shader->preprocess(
- reinterpret_cast<const TBuiltInResource*>(input->resource),
- input->default_version,
- c_shader_profile(input->default_profile),
- input->force_default_version_and_profile != 0,
- input->forward_compatible != 0,
- (EShMessages)c_shader_messages(input->messages),
- &shader->preprocessedGLSL,
- Includer
- );
-}
-
-GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input)
-{
- const char* preprocessedCStr = shader->preprocessedGLSL.c_str();
- shader->shader->setStrings(&preprocessedCStr, 1);
-
- return shader->shader->parse(
- reinterpret_cast<const TBuiltInResource*>(input->resource),
- input->default_version,
- input->forward_compatible != 0,
- (EShMessages)c_shader_messages(input->messages)
- );
-}
-
-GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader) { return shader->shader->getInfoLog(); }
-
-GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader) { return shader->shader->getInfoDebugLog(); }
-
-GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader)
-{
- if (!shader)
- return;
-
- delete (shader->shader);
- delete (shader);
-}
-
-GLSLANG_EXPORT glslang_program_t* glslang_program_create()
-{
- glslang_program_t* p = new glslang_program_t();
- p->program = new glslang::TProgram();
- return p;
-}
-
-GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program)
-{
- if (!program)
- return;
-
- delete (program->program);
- delete (program);
-}
-
-GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader)
-{
- program->program->addShader(shader->shader);
-}
-
-GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages)
-{
- return (int)program->program->link((EShMessages)messages);
-}
-
-GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program)
-{
- return program->program->getInfoLog();
-}
-
-GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program)
-{
- return program->program->getInfoDebugLog();
-}
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
index b77c1f4d44..2f99510925 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh
@@ -1038,12 +1038,12 @@ struct Chain
goto skip;
if (reverse)
- c->buffer->reverse ();
+ _hb_ot_layout_reverse_graphemes (c->buffer);
subtable->apply (c);
if (reverse)
- c->buffer->reverse ();
+ _hb_ot_layout_reverse_graphemes (c->buffer);
(void) c->buffer->message (c->font, "end chainsubtable %d", c->lookup_index);
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index b4f7f72374..be3161a54d 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -396,52 +396,6 @@ hb_buffer_t::set_masks (hb_mask_t value,
}
void
-hb_buffer_t::reverse_range (unsigned int start,
- unsigned int end)
-{
- if (end - start < 2)
- return;
-
- hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
-
- if (have_positions) {
- hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
- }
-}
-
-void
-hb_buffer_t::reverse ()
-{
- if (unlikely (!len))
- return;
-
- reverse_range (0, len);
-}
-
-void
-hb_buffer_t::reverse_clusters ()
-{
- unsigned int i, start, count, last_cluster;
-
- if (unlikely (!len))
- return;
-
- reverse ();
-
- count = len;
- start = 0;
- last_cluster = info[0].cluster;
- for (i = 1; i < count; i++) {
- if (last_cluster != info[i].cluster) {
- reverse_range (start, i);
- start = i;
- last_cluster = info[i].cluster;
- }
- }
- reverse_range (start, i);
-}
-
-void
hb_buffer_t::merge_clusters_impl (unsigned int start,
unsigned int end)
{
@@ -543,7 +497,7 @@ void
hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
{
unsigned int cluster = UINT_MAX;
- cluster = _unsafe_to_break_find_min_cluster (info, start, end, cluster);
+ cluster = _infos_find_min_cluster (info, start, end, cluster);
_unsafe_to_break_set_mask (info, start, end, cluster);
}
void
@@ -559,8 +513,9 @@ hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int en
assert (idx <= end);
unsigned int cluster = UINT_MAX;
- cluster = _unsafe_to_break_find_min_cluster (out_info, start, out_len, cluster);
- cluster = _unsafe_to_break_find_min_cluster (info, idx, end, cluster);
+ cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
+ cluster = _infos_find_min_cluster (info, idx, end, cluster);
+
_unsafe_to_break_set_mask (out_info, start, out_len, cluster);
_unsafe_to_break_set_mask (info, idx, end, cluster);
}
diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh
index bde28933e4..0f8140f1b3 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer.hh
@@ -201,9 +201,55 @@ struct hb_buffer_t
unsigned int cluster);
HB_INTERNAL void add_info (const hb_glyph_info_t &glyph_info);
- HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
- HB_INTERNAL void reverse ();
- HB_INTERNAL void reverse_clusters ();
+ void reverse_range (unsigned start, unsigned end)
+ {
+ hb_array_t<hb_glyph_info_t> (info, len).reverse (start, end);
+ if (have_positions)
+ hb_array_t<hb_glyph_position_t> (pos, len).reverse (start, end);
+ }
+ void reverse () { reverse_range (0, len); }
+
+ template <typename FuncType>
+ void reverse_groups (const FuncType& group,
+ bool merge_clusters = false)
+ {
+ if (unlikely (!len))
+ return;
+
+ unsigned start = 0;
+ unsigned i;
+ for (i = 1; i < len; i++)
+ {
+ if (!group (info[i - 1], info[i]))
+ {
+ if (merge_clusters)
+ this->merge_clusters (start, i);
+ reverse_range (start, i);
+ start = i;
+ }
+ }
+ if (merge_clusters)
+ this->merge_clusters (start, i);
+ reverse_range (start, i);
+
+ reverse ();
+ }
+
+ template <typename FuncType>
+ unsigned group_end (unsigned start, const FuncType& group) const
+ {
+ while (++start < len && group (info[start - 1], info[start]))
+ ;
+
+ return start;
+ }
+
+ static bool _cluster_group_func (const hb_glyph_info_t& a,
+ const hb_glyph_info_t& b)
+ { return a.cluster == b.cluster; }
+
+ void reverse_clusters () { reverse_groups (_cluster_group_func); }
+
HB_INTERNAL void guess_segment_properties ();
HB_INTERNAL void swap_buffers ();
@@ -428,10 +474,10 @@ struct hb_buffer_t
inf.cluster = cluster;
}
- unsigned int
- _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos,
- unsigned int start, unsigned int end,
- unsigned int cluster) const
+ static unsigned
+ _infos_find_min_cluster (const hb_glyph_info_t *infos,
+ unsigned start, unsigned end,
+ unsigned cluster)
{
for (unsigned int i = start; i < end; i++)
cluster = hb_min (cluster, infos[i].cluster);
@@ -450,36 +496,24 @@ struct hb_buffer_t
}
}
- void unsafe_to_break_all () { unsafe_to_break_impl (0, len); }
- void safe_to_break_all ()
+ void clear_glyph_flags (hb_mask_t mask = 0)
{
for (unsigned int i = 0; i < len; i++)
- info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
+ info[i].mask = (info[i].mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
}
};
DECLARE_NULL_INSTANCE (hb_buffer_t);
-/* Loop over clusters. Duplicated in foreach_syllable(). */
-#define foreach_cluster(buffer, start, end) \
+#define foreach_group(buffer, start, end, group_func) \
for (unsigned int \
_count = buffer->len, \
- start = 0, end = _count ? _next_cluster (buffer, 0) : 0; \
+ start = 0, end = _count ? buffer->group_end (0, group_func) : 0; \
start < _count; \
- start = end, end = _next_cluster (buffer, start))
-
-static inline unsigned int
-_next_cluster (hb_buffer_t *buffer, unsigned int start)
-{
- hb_glyph_info_t *info = buffer->info;
- unsigned int count = buffer->len;
-
- unsigned int cluster = info[start].cluster;
- while (++start < count && cluster == info[start].cluster)
- ;
+ start = end, end = buffer->group_end (start, group_func))
- return start;
-}
+#define foreach_cluster(buffer, start, end) \
+ foreach_group (buffer, start, end, hb_buffer_t::_cluster_group_func)
#define HB_BUFFER_XALLOCATE_VAR(b, func, var) \
diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh
index ad800f0f74..7d00d9088a 100644
--- a/thirdparty/harfbuzz/src/hb-config.hh
+++ b/thirdparty/harfbuzz/src/hb-config.hh
@@ -86,8 +86,11 @@
#define HB_NO_LEGACY
#endif
-#ifdef HAVE_CONFIG_OVERRIDE_H
-#include "config-override.h"
+#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
+#ifndef HB_CONFIG_OVERRIDE_H
+#define HB_CONFIG_OVERRIDE_H "config-override.h"
+#endif
+#include HB_CONFIG_OVERRIDE_H
#endif
/* Closure of options. */
diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc
index 4b6c67c1ee..a512f3b8b7 100644
--- a/thirdparty/harfbuzz/src/hb-coretext.cc
+++ b/thirdparty/harfbuzz/src/hb-coretext.cc
@@ -1213,7 +1213,7 @@ resize_and_retry:
}
}
- buffer->unsafe_to_break_all ();
+ buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
#undef FAIL
diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc
index db7b53b259..dea87b8cd0 100644
--- a/thirdparty/harfbuzz/src/hb-directwrite.cc
+++ b/thirdparty/harfbuzz/src/hb-directwrite.cc
@@ -43,14 +43,6 @@
* Functions for using HarfBuzz with DirectWrite fonts.
**/
-/* Declare object creator for dynamic support of DWRITE */
-typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
- DWRITE_FACTORY_TYPE factoryType,
- REFIID iid,
- IUnknown **factory
-);
-
-
/*
* DirectWrite font stream helpers
*/
@@ -145,7 +137,6 @@ public:
struct hb_directwrite_face_data_t
{
- HMODULE dwrite_dll;
IDWriteFactory *dwriteFactory;
IDWriteFontFile *fontFile;
DWriteFontFileStream *fontFileStream;
@@ -167,33 +158,12 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
return nullptr; \
} HB_STMT_END
- data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
- if (unlikely (!data->dwrite_dll))
- FAIL ("Cannot find DWrite.DLL");
-
- t_DWriteCreateFactory p_DWriteCreateFactory;
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-function-type"
-#endif
-
- p_DWriteCreateFactory = (t_DWriteCreateFactory)
- GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
- if (unlikely (!p_DWriteCreateFactory))
- FAIL ("Cannot find DWriteCreateFactory().");
-
HRESULT hr;
// TODO: factory and fontFileLoader should be cached separately
IDWriteFactory* dwriteFactory;
- hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
- (IUnknown**) &dwriteFactory);
+ hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
+ (IUnknown**) &dwriteFactory);
if (unlikely (hr != S_OK))
FAIL ("Failed to run DWriteCreateFactory().");
@@ -257,8 +227,6 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
delete data->fontFileStream;
if (data->faceBlob)
hb_blob_destroy (data->faceBlob);
- if (data->dwrite_dll)
- FreeLibrary (data->dwrite_dll);
if (data)
delete data;
}
@@ -794,6 +762,8 @@ retry_getglyphs:
if (isRightToLeft) hb_buffer_reverse (buffer);
+ buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+
delete [] clusterMap;
delete [] glyphIndices;
delete [] textProperties;
diff --git a/thirdparty/harfbuzz/src/hb-fallback-shape.cc b/thirdparty/harfbuzz/src/hb-fallback-shape.cc
index c5b7c2c230..f8524ecc8e 100644
--- a/thirdparty/harfbuzz/src/hb-fallback-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-fallback-shape.cc
@@ -117,7 +117,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
if (HB_DIRECTION_IS_BACKWARD (direction))
hb_buffer_reverse (buffer);
- buffer->safe_to_break_all ();
+ buffer->clear_glyph_flags ();
return true;
}
diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc
index 97a2c82e68..67691e3ff3 100644
--- a/thirdparty/harfbuzz/src/hb-ft.cc
+++ b/thirdparty/harfbuzz/src/hb-ft.cc
@@ -361,6 +361,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
}
}
+#ifndef HB_NO_VERTICAL
static hb_position_t
hb_ft_get_glyph_v_advance (hb_font_t *font,
void *font_data,
@@ -381,7 +382,9 @@ hb_ft_get_glyph_v_advance (hb_font_t *font,
* have a Y growing upward. Hence the extra negation. */
return (-v + (1<<9)) >> 10;
}
+#endif
+#ifndef HB_NO_VERTICAL
static hb_bool_t
hb_ft_get_glyph_v_origin (hb_font_t *font,
void *font_data,
@@ -409,6 +412,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
return true;
}
+#endif
#ifndef HB_NO_OT_SHAPE_FALLBACK
static hb_position_t
@@ -569,15 +573,20 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
{
hb_font_funcs_t *funcs = hb_font_funcs_create ();
- hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr);
- //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr);
+
+ hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
+
+#ifndef HB_NO_VERTICAL
+ //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
+ hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
+#endif
+
#ifndef HB_NO_OT_SHAPE_FALLBACK
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
#endif
diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc
index 209207f1e5..42420ac0b0 100644
--- a/thirdparty/harfbuzz/src/hb-graphite2.cc
+++ b/thirdparty/harfbuzz/src/hb-graphite2.cc
@@ -439,7 +439,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
if (feats) gr_featureval_destroy (feats);
gr_seg_destroy (seg);
- buffer->unsafe_to_break_all ();
+ buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
return true;
}
diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh
index 87b8ed880d..ad2e45e3c5 100644
--- a/thirdparty/harfbuzz/src/hb-iter.hh
+++ b/thirdparty/harfbuzz/src/hb-iter.hh
@@ -581,6 +581,91 @@ struct
}
HB_FUNCOBJ (hb_zip);
+/* hb_concat() */
+
+template <typename A, typename B>
+struct hb_concat_iter_t :
+ hb_iter_t<hb_concat_iter_t<A, B>, typename A::item_t>
+{
+ hb_concat_iter_t () {}
+ hb_concat_iter_t (A& a, B& b) : a (a), b (b) {}
+ hb_concat_iter_t (const A& a, const B& b) : a (a), b (b) {}
+
+
+ typedef typename A::item_t __item_t__;
+ static constexpr bool is_random_access_iterator =
+ A::is_random_access_iterator &&
+ B::is_random_access_iterator;
+ static constexpr bool is_sorted_iterator = false;
+
+ __item_t__ __item__ () const
+ {
+ if (!a)
+ return *b;
+ return *a;
+ }
+
+ __item_t__ __item_at__ (unsigned i) const
+ {
+ unsigned a_len = a.len ();
+ if (i < a_len)
+ return a[i];
+ return b[i - a_len];
+ }
+
+ bool __more__ () const { return bool (a) || bool (b); }
+
+ unsigned __len__ () const { return a.len () + b.len (); }
+
+ void __next__ ()
+ {
+ if (a)
+ ++a;
+ else
+ ++b;
+ }
+
+ void __forward__ (unsigned n)
+ {
+ if (!n) return;
+ if (!is_random_access_iterator) {
+ while (n-- && *this) {
+ (*this)++;
+ }
+ return;
+ }
+
+ unsigned a_len = a.len ();
+ if (n > a_len) {
+ n -= a_len;
+ a.__forward__ (a_len);
+ b.__forward__ (n);
+ } else {
+ a.__forward__ (n);
+ }
+ }
+
+ hb_concat_iter_t __end__ () const { return hb_concat_iter_t (a.end (), b.end ()); }
+ bool operator != (const hb_concat_iter_t& o) const
+ {
+ return a != o.a
+ || b != o.b;
+ }
+
+ private:
+ A a;
+ B b;
+};
+struct
+{ HB_PARTIALIZE(2);
+ template <typename A, typename B,
+ hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
+ hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>>
+ operator () (A&& a, B&& b) const
+ { return hb_concat_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
+}
+HB_FUNCOBJ (hb_concat);
+
/* hb_apply() */
template <typename Appl>
diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
index c8a2af1e82..d837adc788 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
@@ -93,120 +93,192 @@ struct CmapSubtableFormat0
struct CmapSubtableFormat4
{
+
template<typename Iterator,
+ typename Writer,
hb_requires (hb_is_iterator (Iterator))>
- HBUINT16* serialize_endcode_array (hb_serialize_context_t *c,
- Iterator it)
- {
- HBUINT16 *endCode = c->start_embed<HBUINT16> ();
- hb_codepoint_t prev_endcp = 0xFFFF;
+ void to_ranges (Iterator it, Writer& range_writer)
+ {
+ hb_codepoint_t start_cp = 0, prev_run_start_cp = 0, run_start_cp = 0, end_cp = 0, last_gid = 0;
+ int run_length = 0 , delta = 0, prev_delta = 0;
+
+ enum {
+ FIRST_SUB_RANGE,
+ FOLLOWING_SUB_RANGE,
+ } mode;
+
+ while (it) {
+ // Start a new range
+ start_cp = (*it).first;
+ prev_run_start_cp = (*it).first;
+ run_start_cp = (*it).first;
+ end_cp = (*it).first;
+ last_gid = (*it).second;
+ run_length = 1;
+ prev_delta = 0;
+
+ delta = (*it).second - (*it).first;
+ mode = FIRST_SUB_RANGE;
+ it++;
+
+ while (it) {
+ // Process range
+ hb_codepoint_t next_cp = (*it).first;
+ hb_codepoint_t next_gid = (*it).second;
+ if (next_cp != end_cp + 1) {
+ // Current range is over, stop processing.
+ break;
+ }
- for (const auto& _ : +it)
- {
- if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
- {
- HBUINT16 end_code;
- end_code = prev_endcp;
- c->copy<HBUINT16> (end_code);
- }
- prev_endcp = _.first;
- }
+ if (next_gid == last_gid + 1) {
+ // The current run continues.
+ end_cp = next_cp;
+ run_length++;
+ last_gid = next_gid;
+ it++;
+ continue;
+ }
- {
- // last endCode
- HBUINT16 endcode;
- endcode = prev_endcp;
- if (unlikely (!c->copy<HBUINT16> (endcode))) return nullptr;
- // There must be a final entry with end_code == 0xFFFF.
- if (prev_endcp != 0xFFFF)
- {
- HBUINT16 finalcode;
- finalcode = 0xFFFF;
- if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
+ // A new run is starting, decide if we want to commit the current run.
+ int split_cost = (mode == FIRST_SUB_RANGE) ? 8 : 16;
+ int run_cost = run_length * 2;
+ if (run_cost >= split_cost) {
+ commit_current_range(start_cp,
+ prev_run_start_cp,
+ run_start_cp,
+ end_cp,
+ delta,
+ prev_delta,
+ split_cost,
+ range_writer);
+ start_cp = next_cp;
+ }
+
+ // Start the new run
+ mode = FOLLOWING_SUB_RANGE;
+ prev_run_start_cp = run_start_cp;
+ run_start_cp = next_cp;
+ end_cp = next_cp;
+ prev_delta = delta;
+ delta = next_gid - run_start_cp;
+ run_length = 1;
+ last_gid = next_gid;
+ it++;
}
+
+ // Finalize range
+ commit_current_range (start_cp,
+ prev_run_start_cp,
+ run_start_cp,
+ end_cp,
+ delta,
+ prev_delta,
+ 8,
+ range_writer);
}
- return endCode;
+ if (likely (end_cp != 0xFFFF)) {
+ range_writer (0xFFFF, 0xFFFF, 1);
+ }
}
- template<typename Iterator,
- hb_requires (hb_is_iterator (Iterator))>
- HBUINT16* serialize_startcode_array (hb_serialize_context_t *c,
- Iterator it)
- {
- HBUINT16 *startCode = c->start_embed<HBUINT16> ();
- hb_codepoint_t prev_cp = 0xFFFF;
-
- for (const auto& _ : +it)
- {
- if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
- {
- HBUINT16 start_code;
- start_code = _.first;
- c->copy<HBUINT16> (start_code);
+ /*
+ * Writes the current range as either one or two ranges depending on what is most efficient.
+ */
+ template<typename Writer>
+ void commit_current_range (hb_codepoint_t start,
+ hb_codepoint_t prev_run_start,
+ hb_codepoint_t run_start,
+ hb_codepoint_t end,
+ int run_delta,
+ int previous_run_delta,
+ int split_cost,
+ Writer& range_writer) {
+ bool should_split = false;
+ if (start < run_start && run_start < end) {
+ int run_cost = (end - run_start + 1) * 2;
+ if (run_cost >= split_cost) {
+ should_split = true;
}
+ }
- prev_cp = _.first;
+ // TODO(grieger): handle case where delta is legitimately 0, mark range offset array instead?
+ if (should_split) {
+ if (start == prev_run_start)
+ range_writer (start, run_start - 1, previous_run_delta);
+ else
+ range_writer (start, run_start - 1, 0);
+ range_writer (run_start, end, run_delta);
+ return;
}
- // There must be a final entry with end_code == 0xFFFF.
- if (it.len () == 0 || prev_cp != 0xFFFF)
- {
- HBUINT16 finalcode;
- finalcode = 0xFFFF;
- if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
+
+ if (start == run_start) {
+ // Range is only a run
+ range_writer (start, end, run_delta);
+ return;
}
- return startCode;
+ // Write only a single non-run range.
+ range_writer (start, end, 0);
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
- HBINT16* serialize_idDelta_array (hb_serialize_context_t *c,
- Iterator it,
- HBUINT16 *endCode,
- HBUINT16 *startCode,
- unsigned segcount)
- {
- unsigned i = 0;
- hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF;
- bool use_delta = true;
-
- HBINT16 *idDelta = c->start_embed<HBINT16> ();
- if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size)
- return nullptr;
-
- for (const auto& _ : +it)
- {
- if (_.first == startCode[i])
- {
- use_delta = true;
- start_gid = _.second;
+ unsigned serialize_find_segcount (Iterator it) {
+ struct Counter {
+ unsigned segcount = 0;
+
+ void operator() (hb_codepoint_t start,
+ hb_codepoint_t end,
+ int delta) {
+ segcount++;
}
- else if (_.second != last_gid + 1) use_delta = false;
+ } counter;
- if (_.first == endCode[i])
- {
- HBINT16 delta;
- if (use_delta) delta = (int)start_gid - (int)startCode[i];
- else delta = 0;
- c->copy<HBINT16> (delta);
+ to_ranges (+it, counter);
+ return counter.segcount;
+ }
- i++;
+
+ template<typename Iterator,
+ hb_requires (hb_is_iterator (Iterator))>
+ bool serialize_start_end_delta_arrays (hb_serialize_context_t *c,
+ Iterator it,
+ int segcount)
+ {
+ struct Writer {
+ hb_serialize_context_t *serializer_;
+ HBUINT16* end_code_;
+ HBUINT16* start_code_;
+ HBINT16* id_delta_;
+ int index_;
+
+ Writer(hb_serialize_context_t *serializer)
+ : serializer_(serializer),
+ end_code_(nullptr),
+ start_code_(nullptr),
+ id_delta_(nullptr),
+ index_ (0) {}
+ void operator() (hb_codepoint_t start,
+ hb_codepoint_t end,
+ int delta) {
+ start_code_[index_] = start;
+ end_code_[index_] = end;
+ id_delta_[index_] = delta;
+ index_++;
}
+ } writer(c);
- last_gid = _.second;
- last_cp = _.first;
- }
+ writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
+ c->allocate_size<HBUINT16> (2); // padding
+ writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
+ writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount);
- if (it.len () == 0 || last_cp != 0xFFFF)
- {
- HBINT16 delta;
- delta = 1;
- if (unlikely (!c->copy<HBINT16> (delta))) return nullptr;
- }
+ if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false;
- return idDelta;
+ to_ranges (+it, writer);
+ return true;
}
template<typename Iterator,
@@ -257,22 +329,14 @@ struct CmapSubtableFormat4
if (unlikely (!c->extend_min (this))) return;
this->format = 4;
- //serialize endCode[]
- HBUINT16 *endCode = serialize_endcode_array (c, format4_iter);
- if (unlikely (!endCode)) return;
-
- unsigned segcount = (c->length () - min_size) / HBUINT16::static_size;
-
- // 2 bytes of padding.
- if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding.
-
- // serialize startCode[]
- HBUINT16 *startCode = serialize_startcode_array (c, format4_iter);
- if (unlikely (!startCode)) return;
+ //serialize endCode[], startCode[], idDelta[]
+ HBUINT16* endCode = c->start_embed<HBUINT16> ();
+ unsigned segcount = serialize_find_segcount (format4_iter);
+ if (unlikely (!serialize_start_end_delta_arrays (c, format4_iter, segcount)))
+ return;
- //serialize idDelta[]
- HBINT16 *idDelta = serialize_idDelta_array (c, format4_iter, endCode, startCode, segcount);
- if (unlikely (!idDelta)) return;
+ HBUINT16 *startCode = endCode + segcount + 1;
+ HBINT16 *idDelta = ((HBINT16*)startCode) + segcount;
HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, format4_iter, endCode, startCode, idDelta, segcount);
if (unlikely (!c->check_success (idRangeOffset))) return;
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
index a3c55fa8f4..008422d089 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
@@ -1025,7 +1025,7 @@ struct ClipList
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
- const hb_set_t& glyphset = *c->plan->_glyphset;
+ const hb_set_t& glyphset = *c->plan->_glyphset_colred;
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_map_t new_gid_offset_map;
@@ -1193,7 +1193,7 @@ struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
- const hb_set_t* glyphset = c->plan->_glyphset;
+ const hb_set_t* glyphset = c->plan->_glyphset_colred;
for (const auto& _ : as_array ())
{
@@ -1411,10 +1411,9 @@ struct COLR
const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
{
- if ((unsigned int) gid == 0) // Ignore notdef.
- return nullptr;
const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
- if ((record && (hb_codepoint_t) record->glyphId != gid))
+ if (record == &Null (BaseGlyphRecord) ||
+ (record && (hb_codepoint_t) record->glyphId != gid))
record = nullptr;
return record;
}
@@ -1432,9 +1431,16 @@ struct COLR
TRACE_SUBSET (this);
const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
+ const hb_set_t& glyphset = *c->plan->_glyphset_colred;
auto base_it =
+ hb_range (c->plan->num_output_glyphs ())
+ | hb_filter ([&](hb_codepoint_t new_gid)
+ {
+ hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+ if (glyphset.has (old_gid)) return true;
+ return false;
+ })
| hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -1442,7 +1448,6 @@ struct COLR
const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
if (unlikely (!old_record))
return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
-
BaseGlyphRecord new_record = {};
new_record.glyphId = new_gid;
new_record.numLayers = old_record->numLayers;
@@ -1455,6 +1460,7 @@ struct COLR
auto layer_it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map (reverse_glyph_map)
+ | hb_filter (glyphset)
| hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
{
const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
diff --git a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh
index ffbbb1bc53..eff09838af 100644
--- a/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-face-table-list.hh
@@ -67,8 +67,11 @@ HB_OT_ACCELERATOR (OT, meta)
#endif
/* Vertical layout. */
+#ifndef HB_NO_VERTICAL
HB_OT_TABLE (OT, vhea)
HB_OT_ACCELERATOR (OT, vmtx)
+HB_OT_TABLE (OT, VORG)
+#endif
/* TrueType outlines. */
HB_OT_ACCELERATOR (OT, glyf)
@@ -77,7 +80,6 @@ HB_OT_ACCELERATOR (OT, glyf)
#ifndef HB_NO_CFF
HB_OT_ACCELERATOR (OT, cff1)
HB_OT_ACCELERATOR (OT, cff2)
-HB_OT_TABLE (OT, VORG)
#endif
/* OpenType variations. */
diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc
index 5c044c1c4f..9f0359a773 100644
--- a/thirdparty/harfbuzz/src/hb-ot-font.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-font.cc
@@ -118,6 +118,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
}
}
+#ifndef HB_NO_VERTICAL
static void
hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
unsigned count,
@@ -137,7 +138,9 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
}
}
+#endif
+#ifndef HB_NO_VERTICAL
static hb_bool_t
hb_ot_get_glyph_v_origin (hb_font_t *font,
void *font_data,
@@ -150,14 +153,12 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
*x = font->get_glyph_h_advance (glyph) / 2;
-#ifndef HB_NO_OT_FONT_CFF
const OT::VORG &VORG = *ot_face->VORG;
if (VORG.has_data ())
{
*y = font->em_scale_y (VORG.get_y_origin (glyph));
return true;
}
-#endif
hb_glyph_extents_t extents = {0};
if (ot_face->glyf->get_extents (font, glyph, &extents))
@@ -174,6 +175,7 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
return true;
}
+#endif
static hb_bool_t
hb_ot_get_glyph_extents (hb_font_t *font,
@@ -242,6 +244,7 @@ hb_ot_get_font_h_extents (hb_font_t *font,
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, &metrics->line_gap);
}
+#ifndef HB_NO_VERTICAL
static hb_bool_t
hb_ot_get_font_v_extents (hb_font_t *font,
void *font_data HB_UNUSED,
@@ -252,6 +255,7 @@ hb_ot_get_font_v_extents (hb_font_t *font,
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) &&
_hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap);
}
+#endif
static inline void free_static_ot_funcs ();
@@ -261,17 +265,23 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
{
hb_font_funcs_t *funcs = hb_font_funcs_create ();
- hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
- hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
+
+ hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
- hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
+
+#ifndef HB_NO_VERTICAL
+ hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
+ hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
+#endif
+
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
+
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
index 6b419ea1ac..6aa34295c7 100644
--- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
@@ -93,22 +93,16 @@ struct glyf
template<typename Iterator,
hb_requires (hb_is_source_of (Iterator, unsigned int))>
static bool
- _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets)
+ _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
{
- unsigned max_offset =
- + padded_offsets
- | hb_reduce (hb_add, 0)
- ;
unsigned num_offsets = padded_offsets.len () + 1;
- bool use_short_loca = max_offset < 0x1FFFF;
unsigned entry_size = use_short_loca ? 2 : 4;
char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
if (unlikely (!loca_prime_data)) return false;
- DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d "
- "max_offset %d size %d",
- entry_size, num_offsets, max_offset, entry_size * num_offsets);
+ DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
+ entry_size, num_offsets, entry_size * num_offsets);
if (use_short_loca)
_write_loca (padded_offsets, 1, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
@@ -151,11 +145,12 @@ struct glyf
template <typename Iterator>
bool serialize (hb_serialize_context_t *c,
Iterator it,
+ bool use_short_loca,
const hb_subset_plan_t *plan)
{
TRACE_SERIALIZE (this);
unsigned init_len = c->length ();
- for (const auto &_ : it) _.serialize (c, plan);
+ for (const auto &_ : it) _.serialize (c, use_short_loca, plan);
/* As a special case when all glyph in the font are empty, add a zero byte
* to the table, so that OTS doesn’t reject it, and to make the table work
@@ -183,16 +178,28 @@ struct glyf
hb_vector_t<SubsetGlyph> glyphs;
_populate_subset_glyphs (c->plan, &glyphs);
- glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan);
-
auto padded_offsets =
+ hb_iter (glyphs)
| hb_map (&SubsetGlyph::padded_size)
;
+ unsigned max_offset = + padded_offsets | hb_reduce (hb_add, 0);
+ bool use_short_loca = max_offset < 0x1FFFF;
+
+
+ glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
+ if (!use_short_loca) {
+ padded_offsets =
+ + hb_iter (glyphs)
+ | hb_map (&SubsetGlyph::length)
+ ;
+ }
+
+
if (unlikely (c->serializer->in_error ())) return_trace (false);
return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
- padded_offsets)));
+ padded_offsets,
+ use_short_loca)));
}
template <typename SubsetGlyph>
@@ -792,10 +799,23 @@ struct glyf
hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
{
for (unsigned i = 0; i < PHANTOM_COUNT; ++i) phantoms[i].init ();
- int h_delta = (int) header->xMin - glyf_accelerator.hmtx->get_side_bearing (gid);
- int v_orig = (int) header->yMax + glyf_accelerator.vmtx->get_side_bearing (gid);
+ int h_delta = (int) header->xMin -
+ glyf_accelerator.hmtx->get_side_bearing (gid);
+ int v_orig = (int) header->yMax +
+#ifndef HB_NO_VERTICAL
+ glyf_accelerator.vmtx->get_side_bearing (gid)
+#else
+ 0
+#endif
+ ;
unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid);
- unsigned v_adv = glyf_accelerator.vmtx->get_advance (gid);
+ unsigned v_adv =
+#ifndef HB_NO_VERTICAL
+ glyf_accelerator.vmtx->get_advance (gid)
+#else
+ - font->face->get_upem ()
+#endif
+ ;
phantoms[PHANTOM_LEFT].x = h_delta;
phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
phantoms[PHANTOM_TOP].y = v_orig;
@@ -910,7 +930,9 @@ struct glyf
gvar = nullptr;
#endif
hmtx = nullptr;
+#ifndef HB_NO_VERTICAL
vmtx = nullptr;
+#endif
face = face_;
const OT::head &head = *face->table.head;
if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
@@ -924,7 +946,9 @@ struct glyf
gvar = face->table.gvar;
#endif
hmtx = face->table.hmtx;
+#ifndef HB_NO_VERTICAL
vmtx = face->table.vmtx;
+#endif
num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
@@ -1037,7 +1061,11 @@ struct glyf
success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms));
if (unlikely (!success))
- return is_vertical ? vmtx->get_advance (gid) : hmtx->get_advance (gid);
+ return
+#ifndef HB_NO_VERTICAL
+ is_vertical ? vmtx->get_advance (gid) :
+#endif
+ hmtx->get_advance (gid);
float result = is_vertical
? phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y
@@ -1053,7 +1081,11 @@ struct glyf
contour_point_t phantoms[PHANTOM_COUNT];
if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms))))
- return is_vertical ? vmtx->get_side_bearing (gid) : hmtx->get_side_bearing (gid);
+ return
+#ifndef HB_NO_VERTICAL
+ is_vertical ? vmtx->get_side_bearing (gid) :
+#endif
+ hmtx->get_side_bearing (gid);
return is_vertical
? ceilf (phantoms[PHANTOM_TOP].y) - extents.y_bearing
@@ -1250,7 +1282,9 @@ struct glyf
const gvar_accelerator_t *gvar;
#endif
const hmtx_accelerator_t *hmtx;
+#ifndef HB_NO_VERTICAL
const vmtx_accelerator_t *vmtx;
+#endif
private:
bool short_offset;
@@ -1269,13 +1303,14 @@ struct glyf
hb_bytes_t dest_end; /* region of source_glyph to copy second */
bool serialize (hb_serialize_context_t *c,
+ bool use_short_loca,
const hb_subset_plan_t *plan) const
{
TRACE_SERIALIZE (this);
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
- unsigned int pad_length = padding ();
+ unsigned int pad_length = use_short_loca ? padding () : 0;
DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
HBUINT8 pad;
diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
index 4038329938..7d2d2d3eb8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
@@ -165,7 +165,14 @@ struct hmtxvmtx
{
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
- num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
+ num_advances = T::is_horizontal ?
+ face->table.hhea->numberOfLongMetrics :
+#ifndef HB_NO_VERTICAL
+ face->table.vhea->numberOfLongMetrics
+#else
+ 0
+#endif
+ ;
table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag);
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index 882c3ae96f..4fb1893435 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -68,8 +68,8 @@
#define HB_MAX_FEATURE_INDICES 1500
#endif
-#ifndef HB_MAX_LOOKUP_INDICES
-#define HB_MAX_LOOKUP_INDICES 20000
+#ifndef HB_MAX_LOOKUP_VISIT_COUNT
+#define HB_MAX_LOOKUP_VISIT_COUNT 35000
#endif
@@ -173,7 +173,7 @@ struct hb_subset_layout_context_t :
bool visitLookupIndex()
{
lookup_index_count++;
- return lookup_index_count < HB_MAX_LOOKUP_INDICES;
+ return lookup_index_count < HB_MAX_LOOKUP_VISIT_COUNT;
}
hb_subset_context_t *subset_context;
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
index a8fb5c7acb..6db3e08940 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
@@ -118,7 +118,13 @@ struct ValueFormat : HBUINT16
if (!format) return ret;
hb_font_t *font = c->font;
- bool horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction);
+ bool horizontal =
+#ifndef HB_NO_VERTICAL
+ HB_DIRECTION_IS_HORIZONTAL (c->direction)
+#else
+ true
+#endif
+ ;
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
index 710c5fbbb9..b7ce30135e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
@@ -566,7 +566,7 @@ struct AlternateSet
{
/* Maybe we can do better than unsafe-to-break all; but since we are
* changing random state, it would be hard to track that. Good 'nough. */
- c->buffer->unsafe_to_break_all ();
+ c->buffer->unsafe_to_break (0, c->buffer->len);
alt_index = c->random_number () % count + 1;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index 6bc06b50ed..191d3bebc5 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -81,12 +81,15 @@ struct hb_closure_context_t :
nesting_level_left++;
}
+ void reset_lookup_visit_count ()
+ { lookup_count = 0; }
+
bool lookup_limit_exceeded ()
- { return lookup_count > HB_MAX_LOOKUP_INDICES; }
+ { return lookup_count > HB_MAX_LOOKUP_VISIT_COUNT; }
bool should_visit_lookup (unsigned int lookup_index)
{
- if (lookup_count++ > HB_MAX_LOOKUP_INDICES)
+ if (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT)
return false;
if (is_lookup_done (lookup_index))
@@ -211,7 +214,11 @@ struct hb_closure_lookups_context_t :
return;
/* Return if new lookup was recursed to before. */
- if (is_lookup_visited (lookup_index))
+ if (lookup_limit_exceeded ()
+ || visited_lookups->in_error ()
+ || visited_lookups->has (lookup_index))
+ // Don't increment lookup count here, that will be done in the call to closure_lookups()
+ // made by recurse_func.
return;
nesting_level_left--;
@@ -226,12 +233,20 @@ struct hb_closure_lookups_context_t :
{ inactive_lookups->add (lookup_index); }
bool lookup_limit_exceeded ()
- { return lookup_count > HB_MAX_LOOKUP_INDICES; }
+ {
+ bool ret = lookup_count > HB_MAX_LOOKUP_VISIT_COUNT;
+ if (ret)
+ DEBUG_MSG (SUBSET, nullptr, "lookup visit count limit exceeded in lookup closure!");
+ return ret; }
bool is_lookup_visited (unsigned lookup_index)
{
- if (unlikely (lookup_count++ > HB_MAX_LOOKUP_INDICES))
+ if (unlikely (lookup_count++ > HB_MAX_LOOKUP_VISIT_COUNT))
+ {
+ DEBUG_MSG (SUBSET, nullptr, "total visited lookup count %u exceeds max limit, lookup %u is dropped.",
+ lookup_count, lookup_index);
return true;
+ }
if (unlikely (visited_lookups->in_error ()))
return true;
@@ -1303,8 +1318,7 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
}
hb_set_add (covered_seq_indicies, seqIndex);
- if (pos_glyphs)
- c->push_cur_active_glyphs (pos_glyphs);
+ c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs);
unsigned endIndex = inputCount;
if (context_format == ContextFormat::CoverageBasedContext)
@@ -1312,10 +1326,9 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex);
- if (pos_glyphs) {
- c->pop_cur_done_glyphs ();
+ c->pop_cur_done_glyphs ();
+ if (pos_glyphs)
hb_set_destroy (pos_glyphs);
- }
}
hb_set_destroy (covered_seq_indicies);
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index 4e1d23eba5..60733648c1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -1530,6 +1530,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
unsigned int glyphs_length;
do
{
+ c.reset_lookup_visit_count ();
glyphs_length = glyphs->get_population ();
if (lookups)
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh
index b15d053835..2c825e0c81 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh
@@ -350,24 +350,20 @@ _hb_glyph_info_is_continuation (const hb_glyph_info_t *info)
{
return info->unicode_props() & UPROPS_MASK_CONTINUATION;
}
-/* Loop over grapheme. Based on foreach_cluster(). */
-#define foreach_grapheme(buffer, start, end) \
- for (unsigned int \
- _count = buffer->len, \
- start = 0, end = _count ? _hb_next_grapheme (buffer, 0) : 0; \
- start < _count; \
- start = end, end = _hb_next_grapheme (buffer, start))
-static inline unsigned int
-_hb_next_grapheme (hb_buffer_t *buffer, unsigned int start)
-{
- hb_glyph_info_t *info = buffer->info;
- unsigned int count = buffer->len;
+static inline bool
+_hb_grapheme_group_func (const hb_glyph_info_t& a HB_UNUSED,
+ const hb_glyph_info_t& b)
+{ return _hb_glyph_info_is_continuation (&b); }
- while (++start < count && _hb_glyph_info_is_continuation (&info[start]))
- ;
+#define foreach_grapheme(buffer, start, end) \
+ foreach_group (buffer, start, end, _hb_grapheme_group_func)
- return start;
+static inline void
+_hb_ot_layout_reverse_graphemes (hb_buffer_t *buffer)
+{
+ buffer->reverse_groups (_hb_grapheme_group_func,
+ buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
}
static inline bool
diff --git a/thirdparty/harfbuzz/src/hb-ot-math-table.hh b/thirdparty/harfbuzz/src/hb-ot-math-table.hh
index c2e365dbd6..8d0b4317c3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-math-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-math-table.hh
@@ -511,7 +511,8 @@ struct MathGlyphInfo
| hb_map_retains_sorting (glyph_map)
;
- out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
+ if (it) out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
+ else out->extendedShapeCoverage = 0;
out->mathKernInfo.serialize_subset (c, mathKernInfo, this);
return_trace (true);
@@ -884,8 +885,11 @@ struct MathVariants
if (!o) return_trace (false);
o->serialize_subset (c, glyphConstruction[i], this);
}
-
- out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
+
+ if (new_vert_coverage)
+ out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
+
+ if (new_hori_coverage)
out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ());
return_trace (true);
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
index 72aeff82d6..dbd4a1ffbe 100644
--- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
@@ -77,6 +77,7 @@ _hb_ot_metrics_get_position_common (hb_font_t *font,
(face->table.TABLE->has_data () && \
(position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
+
case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
GET_METRIC_Y (hhea, ascender);
@@ -86,9 +87,13 @@ _hb_ot_metrics_get_position_common (hb_font_t *font,
case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
GET_METRIC_Y (hhea, lineGap);
+
+#ifndef HB_NO_VERTICAL
case HB_OT_METRICS_TAG_VERTICAL_ASCENDER: return GET_METRIC_X (vhea, ascender);
case HB_OT_METRICS_TAG_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: return GET_METRIC_X (vhea, lineGap);
+#endif
+
#undef GET_METRIC_Y
#undef GET_METRIC_X
#undef GET_VAR
@@ -158,9 +163,11 @@ hb_ot_metrics_get_position (hb_font_t *font,
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
+#ifndef HB_NO_VERTICAL
case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: return GET_METRIC_Y (vhea, caretOffset);
+#endif
case HB_OT_METRICS_TAG_X_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sxHeight);
case HB_OT_METRICS_TAG_CAP_HEIGHT: return GET_METRIC_Y (OS2->v2 (), sCapHeight);
case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: return GET_METRIC_X (OS2, ySubscriptXSize);
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc
index 4e8a4bc3d1..4dde3520d8 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc
@@ -628,20 +628,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
(HB_DIRECTION_IS_VERTICAL (direction) &&
direction != HB_DIRECTION_TTB))
{
-
- if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
- foreach_grapheme (buffer, start, end)
- {
- buffer->merge_clusters (start, end);
- buffer->reverse_range (start, end);
- }
- else
- foreach_grapheme (buffer, start, end)
- /* form_clusters() merged clusters already, we don't merge. */
- buffer->reverse_range (start, end);
-
- buffer->reverse ();
-
+ _hb_ot_layout_reverse_graphemes (buffer);
buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction);
}
}
@@ -651,6 +638,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
* Substitute
*/
+#ifndef HB_NO_VERTICAL
static hb_codepoint_t
hb_vert_char_for (hb_codepoint_t u)
{
@@ -701,6 +689,7 @@ hb_vert_char_for (hb_codepoint_t u)
return u;
}
+#endif
static inline void
hb_ot_rotate_chars (const hb_ot_shape_context_t *c)
@@ -723,6 +712,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c)
}
}
+#ifndef HB_NO_VERTICAL
if (HB_DIRECTION_IS_VERTICAL (c->target_direction) && !c->plan->has_vert)
{
for (unsigned int i = 0; i < count; i++) {
@@ -731,6 +721,7 @@ hb_ot_rotate_chars (const hb_ot_shape_context_t *c)
info[i].codepoint = codepoint;
}
}
+#endif
}
static inline void
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
index fc9bffc23f..2c6316df4f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
@@ -6,7 +6,7 @@
*
* on files with these headers:
*
- * <meta name="updated_at" content="2021-09-02 09:40 PM" />
+ * <meta name="updated_at" content="2021-12-09 12:01 AM" />
* File-Date: 2021-08-06
*/
@@ -933,6 +933,7 @@ static const LangTag ot_languages[] = {
{"mnp", HB_TAG('Z','H','S',' ')}, /* Min Bei Chinese -> Chinese, Simplified */
{"mns", HB_TAG('M','A','N',' ')}, /* Mansi */
{"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
+ {"mnw", HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */
{"mnx", HB_TAG_NONE }, /* Manikion != Manx */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */
{"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */
@@ -1422,6 +1423,7 @@ static const LangTag ot_languages[] = {
{"tia", HB_TAG('B','B','R',' ')}, /* Tidikelt Tamazight -> Berber */
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
/*{"tiv", HB_TAG('T','I','V',' ')},*/ /* Tiv */
+/*{"tjl", HB_TAG('T','J','L',' ')},*/ /* Tai Laing */
{"tjo", HB_TAG('B','B','R',' ')}, /* Temacine Tamazight -> Berber */
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
{"tkg", HB_TAG('M','L','G',' ')}, /* Tesaka Malagasy -> Malagasy */
@@ -2521,6 +2523,14 @@ hb_ot_tags_from_complex_language (const char *lang_str,
*count = 1;
return true;
}
+ if (0 == strncmp (&lang_str[1], "nw-", 3)
+ && subtag_matches (lang_str, limit, "-th"))
+ {
+ /* Mon; Thailand */
+ tags[0] = HB_TAG('M','O','N','T'); /* Thailand Mon */
+ *count = 1;
+ return true;
+ }
break;
case 'n':
if (lang_matches (&lang_str[1], "an-hant-hk"))
@@ -2884,6 +2894,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
return hb_language_from_string ("man", -1); /* Mandingo [macrolanguage] */
case HB_TAG('M','O','L',' '): /* Moldavian */
return hb_language_from_string ("ro-MD", -1); /* Romanian; Moldova */
+ case HB_TAG('M','O','N','T'): /* Thailand Mon */
+ return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */
case HB_TAG('M','Y','N',' '): /* Mayan */
return hb_language_from_string ("myn", -1); /* Mayan [family] */
case HB_TAG('N','A','H',' '): /* Nahuatl */
diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh
index 26faa56ea8..5c46b4cccc 100644
--- a/thirdparty/harfbuzz/src/hb-repacker.hh
+++ b/thirdparty/harfbuzz/src/hb-repacker.hh
@@ -100,12 +100,18 @@ struct graph_t
bool is_leaf () const
{
- return !obj.links.length;
+ return !obj.real_links.length && !obj.virtual_links.length;
}
- void raise_priority ()
+ bool raise_priority ()
{
+ if (has_max_priority ()) return false;
priority++;
+ return true;
+ }
+
+ bool has_max_priority () const {
+ return priority >= 3;
}
int64_t modified_distance (unsigned order) const
@@ -115,15 +121,22 @@ struct graph_t
// it's parent where possible.
int64_t modified_distance =
- hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFF);
- return (modified_distance << 22) | (0x003FFFFF & order);
+ hb_min (hb_max(distance + distance_modifier (), 0), 0x7FFFFFFFFFF);
+ if (has_max_priority ()) {
+ modified_distance = 0;
+ }
+ return (modified_distance << 18) | (0x003FFFF & order);
}
int64_t distance_modifier () const
{
if (!priority) return 0;
int64_t table_size = obj.tail - obj.head;
- return -(table_size - table_size / (1 << hb_min(priority, 16u)));
+
+ if (priority == 1)
+ return -table_size / 2;
+
+ return -table_size;
}
};
@@ -164,9 +177,10 @@ struct graph_t
if (check_success (!vertices_.in_error ()))
v->obj = *objects[i];
if (!removed_nil) continue;
- for (unsigned i = 0; i < v->obj.links.length; i++)
- // Fix indices to account for removed nil object.
- v->obj.links[i].objidx--;
+ // Fix indices to account for removed nil object.
+ for (auto& l : v->obj.all_links_writer ()) {
+ l.objidx--;
+ }
}
}
@@ -203,26 +217,46 @@ struct graph_t
/*
* serialize graph into the provided serialization buffer.
*/
- void serialize (hb_serialize_context_t* c) const
+ hb_blob_t* serialize () const
{
- c->start_serialize<void> ();
+ hb_vector_t<char> buffer;
+ size_t size = serialized_length ();
+ if (!buffer.alloc (size)) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
+ return nullptr;
+ }
+ hb_serialize_context_t c((void *) buffer, size);
+
+ c.start_serialize<void> ();
for (unsigned i = 0; i < vertices_.length; i++) {
- c->push ();
+ c.push ();
size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
- char* start = c->allocate_size <char> (size);
- if (!start) return;
+ char* start = c.allocate_size <char> (size);
+ if (!start) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Buffer out of space.");
+ return nullptr;
+ }
memcpy (start, vertices_[i].obj.head, size);
- for (const auto& link : vertices_[i].obj.links)
- serialize_link (link, start, c);
+ // Only real links needs to be serialized.
+ for (const auto& link : vertices_[i].obj.real_links)
+ serialize_link (link, start, &c);
// All duplications are already encoded in the graph, so don't
// enable sharing during packing.
- c->pop_pack (false);
+ c.pop_pack (false);
}
- c->end_serialize ();
+ c.end_serialize ();
+
+ if (c.in_error ()) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Error during serialization. Err flag: %d",
+ c.errors);
+ return nullptr;
+ }
+
+ return c.copy_blob ();
}
/*
@@ -260,7 +294,7 @@ struct graph_t
sorted_graph[new_id] = next;
id_map[next_id] = new_id--;
- for (const auto& link : next.obj.links) {
+ for (const auto& link : next.obj.all_links ()) {
removed_edges[link.objidx]++;
if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
queue.push (link.objidx);
@@ -314,7 +348,7 @@ struct graph_t
sorted_graph[new_id] = next;
id_map[next_id] = new_id--;
- for (const auto& link : next.obj.links) {
+ for (const auto& link : next.obj.all_links ()) {
removed_edges[link.objidx]++;
if (!(vertices_[link.objidx].incoming_edges () - removed_edges[link.objidx]))
// Add the order that the links were encountered to the priority.
@@ -348,7 +382,8 @@ struct graph_t
hb_set_t roots;
for (unsigned i = 0; i <= root_index; i++)
{
- for (auto& l : vertices_[i].obj.links)
+ // Only real links can form 32 bit spaces
+ for (auto& l : vertices_[i].obj.real_links)
{
if (l.width == 4 && !l.is_signed)
{
@@ -466,7 +501,7 @@ struct graph_t
void find_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& subgraph)
{
- for (const auto& link : vertices_[node_idx].obj.links)
+ for (const auto& link : vertices_[node_idx].obj.all_links ())
{
if (subgraph.has (link.objidx))
{
@@ -482,7 +517,7 @@ struct graph_t
{
if (subgraph.has (node_idx)) return;
subgraph.add (node_idx);
- for (const auto& link : vertices_[node_idx].obj.links)
+ for (const auto& link : vertices_[node_idx].obj.all_links ())
find_subgraph (link.objidx, subgraph);
}
@@ -497,7 +532,7 @@ struct graph_t
return;
index_map.set (node_idx, duplicate (node_idx));
- for (const auto& l : object (node_idx).links) {
+ for (const auto& l : object (node_idx).all_links ()) {
duplicate_subgraph (l.objidx, index_map);
}
}
@@ -523,13 +558,19 @@ struct graph_t
clone->parents.reset ();
unsigned clone_idx = vertices_.length - 2;
- for (const auto& l : child.obj.links)
+ for (const auto& l : child.obj.real_links)
{
- clone->obj.links.push (l);
+ clone->obj.real_links.push (l);
+ vertices_[l.objidx].parents.push (clone_idx);
+ }
+ for (const auto& l : child.obj.virtual_links)
+ {
+ clone->obj.virtual_links.push (l);
vertices_[l.objidx].parents.push (clone_idx);
}
- check_success (!clone->obj.links.in_error ());
+ check_success (!clone->obj.real_links.in_error ());
+ check_success (!clone->obj.virtual_links.in_error ());
// The last object is the root of the graph, so swap back the root to the end.
// The root's obj idx does change, however since it's root nothing else refers to it.
@@ -539,7 +580,7 @@ struct graph_t
vertices_[vertices_.length - 1] = root;
// Since the root moved, update the parents arrays of all children on the root.
- for (const auto& l : root.obj.links)
+ for (const auto& l : root.obj.all_links ())
vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
return clone_idx;
@@ -555,7 +596,7 @@ struct graph_t
update_parents ();
unsigned links_to_child = 0;
- for (const auto& l : vertices_[parent_idx].obj.links)
+ for (const auto& l : vertices_[parent_idx].obj.all_links ())
{
if (l.objidx == child_idx) links_to_child++;
}
@@ -578,9 +619,8 @@ struct graph_t
if (parent_idx == clone_idx) parent_idx++;
auto& parent = vertices_[parent_idx];
- for (unsigned i = 0; i < parent.obj.links.length; i++)
+ for (auto& l : parent.obj.all_links_writer ())
{
- auto& l = parent.obj.links[i];
if (l.objidx != child_idx)
continue;
@@ -593,7 +633,7 @@ struct graph_t
/*
* Raises the sorting priority of all children.
*/
- void raise_childrens_priority (unsigned parent_idx)
+ bool raise_childrens_priority (unsigned parent_idx)
{
DEBUG_MSG (SUBSET_REPACK, nullptr, " Raising priority of all children of %d",
parent_idx);
@@ -601,8 +641,10 @@ struct graph_t
// to invalidate positions. It does not change graph structure so no need
// to update distances or edge counts.
auto& parent = vertices_[parent_idx].obj;
- for (unsigned i = 0; i < parent.links.length; i++)
- vertices_[parent.links[i].objidx].raise_priority ();
+ bool made_change = false;
+ for (auto& l : parent.all_links_writer ())
+ made_change |= vertices_[l.objidx].raise_priority ();
+ return made_change;
}
/*
@@ -615,7 +657,8 @@ struct graph_t
for (int parent_idx = vertices_.length - 1; parent_idx >= 0; parent_idx--)
{
- for (const auto& link : vertices_[parent_idx].obj.links)
+ // Don't need to check virtual links for overflow
+ for (const auto& link : vertices_[parent_idx].obj.real_links)
{
int64_t offset = compute_offset (parent_idx, link);
if (is_valid_offset (offset, link))
@@ -655,8 +698,10 @@ struct graph_t
if (!DEBUG_ENABLED(SUBSET_REPACK)) return;
update_parents ();
+ int limit = 10;
for (const auto& o : overflows)
{
+ if (!limit--) break;
const auto& parent = vertices_[o.parent];
const auto& child = vertices_[o.child];
DEBUG_MSG (SUBSET_REPACK, nullptr,
@@ -665,13 +710,16 @@ struct graph_t
"%4d (%4d in, %4d out, space %2d)",
o.parent,
parent.incoming_edges (),
- parent.obj.links.length,
+ parent.obj.real_links.length + parent.obj.virtual_links.length,
space_for (o.parent),
o.child,
child.incoming_edges (),
- child.obj.links.length,
+ child.obj.real_links.length + child.obj.virtual_links.length,
space_for (o.child));
}
+ if (overflows.length > 10) {
+ DEBUG_MSG (SUBSET_REPACK, nullptr, " ... plus %d more overflows.", overflows.length - 10);
+ }
}
unsigned num_roots_for_space (unsigned space) const
@@ -684,12 +732,19 @@ struct graph_t
return num_roots_for_space_.length;
}
- void move_to_new_space (unsigned index)
+ void move_to_new_space (const hb_set_t& indices)
{
- auto& node = vertices_[index];
- num_roots_for_space_.push (1);
- num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
- node.space = num_roots_for_space_.length - 1;
+ num_roots_for_space_.push (0);
+ unsigned new_space = num_roots_for_space_.length - 1;
+
+ for (unsigned index : indices) {
+ auto& node = vertices_[index];
+ num_roots_for_space_[node.space] = num_roots_for_space_[node.space] - 1;
+ num_roots_for_space_[new_space] = num_roots_for_space_[new_space] + 1;
+ node.space = new_space;
+ distance_invalid = true;
+ positions_invalid = true;
+ }
}
unsigned space_for (unsigned index, unsigned* root = nullptr) const
@@ -716,6 +771,15 @@ struct graph_t
private:
+ size_t serialized_length () const {
+ size_t total_size = 0;
+ for (unsigned i = 0; i < vertices_.length; i++) {
+ size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+ total_size += size;
+ }
+ return total_size;
+ }
+
/*
* Returns the numbers of incoming edges that are 32bits wide.
*/
@@ -728,7 +792,8 @@ struct graph_t
if (visited.has (p)) continue;
visited.add (p);
- for (const auto& l : vertices_[p].obj.links)
+ // Only real links can be wide
+ for (const auto& l : vertices_[p].obj.real_links)
{
if (l.objidx == node_idx && l.width == 4 && !l.is_signed)
{
@@ -755,7 +820,7 @@ struct graph_t
for (unsigned p = 0; p < vertices_.length; p++)
{
- for (auto& l : vertices_[p].obj.links)
+ for (auto& l : vertices_[p].obj.all_links ())
{
vertices_[l.objidx].parents.push (p);
}
@@ -823,7 +888,7 @@ struct graph_t
int64_t next_distance = vertices_[next_idx].distance;
visited[next_idx] = true;
- for (const auto& link : next.obj.links)
+ for (const auto& link : next.obj.all_links ())
{
if (visited[link.objidx]) continue;
@@ -922,9 +987,8 @@ struct graph_t
if (!id_map) return;
for (unsigned i : subgraph)
{
- for (unsigned j = 0; j < vertices_[i].obj.links.length; j++)
+ for (auto& link : vertices_[i].obj.all_links_writer ())
{
- auto& link = vertices_[i].obj.links[j];
if (!id_map.has (link.objidx)) continue;
if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
@@ -942,9 +1006,8 @@ struct graph_t
for (unsigned i = 0; i < sorted_graph->length; i++)
{
(*sorted_graph)[i].remap_parents (id_map);
- for (unsigned j = 0; j < (*sorted_graph)[i].obj.links.length; j++)
+ for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
{
- auto& link = (*sorted_graph)[i].obj.links[j];
link.objidx = id_map[link.objidx];
}
}
@@ -1023,7 +1086,7 @@ struct graph_t
const auto& v = vertices_[start_idx];
// Graph is treated as undirected so search children and parents of start_idx
- for (const auto& l : v.obj.links)
+ for (const auto& l : v.obj.all_links ())
find_connected_nodes (l.objidx, targets, visited, connected);
for (unsigned p : v.parents)
@@ -1044,27 +1107,50 @@ struct graph_t
static bool _try_isolating_subgraphs (const hb_vector_t<graph_t::overflow_record_t>& overflows,
graph_t& sorted_graph)
{
+ unsigned space = 0;
+ hb_set_t roots_to_isolate;
+
for (int i = overflows.length - 1; i >= 0; i--)
{
const graph_t::overflow_record_t& r = overflows[i];
- unsigned root = 0;
- unsigned space = sorted_graph.space_for (r.parent, &root);
- if (!space) continue;
- if (sorted_graph.num_roots_for_space (space) <= 1) continue;
- DEBUG_MSG (SUBSET_REPACK, nullptr, "Overflow in space %d moving subgraph %d to space %d.",
- space,
- root,
- sorted_graph.next_space ());
+ unsigned root;
+ unsigned overflow_space = sorted_graph.space_for (r.parent, &root);
+ if (!overflow_space) continue;
+ if (sorted_graph.num_roots_for_space (overflow_space) <= 1) continue;
- hb_set_t roots;
- roots.add (root);
- sorted_graph.isolate_subgraph (roots);
- for (unsigned new_root : roots)
- sorted_graph.move_to_new_space (new_root);
- return true;
+ if (!space) {
+ space = overflow_space;
+ }
+
+ if (space == overflow_space)
+ roots_to_isolate.add(root);
}
- return false;
+
+ if (!roots_to_isolate) return false;
+
+ unsigned maximum_to_move = hb_max ((sorted_graph.num_roots_for_space (space) / 2u), 1u);
+ if (roots_to_isolate.get_population () > maximum_to_move) {
+ // Only move at most half of the roots in a space at a time.
+ unsigned extra = roots_to_isolate.get_population () - maximum_to_move;
+ while (extra--) {
+ unsigned root = HB_SET_VALUE_INVALID;
+ roots_to_isolate.previous (&root);
+ roots_to_isolate.del (root);
+ }
+ }
+
+ DEBUG_MSG (SUBSET_REPACK, nullptr,
+ "Overflow in space %d (%d roots). Moving %d roots to space %d.",
+ space,
+ sorted_graph.num_roots_for_space (space),
+ roots_to_isolate.get_population (),
+ sorted_graph.next_space ());
+
+ sorted_graph.isolate_subgraph (roots_to_isolate);
+ sorted_graph.move_to_new_space (roots_to_isolate);
+
+ return true;
}
static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& overflows,
@@ -1093,16 +1179,16 @@ static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& o
// TODO(garretrieger): initially limiting this to leaf's since they can be
// moved closer with fewer consequences. However, this can
// likely can be used for non-leafs as well.
- // TODO(garretrieger): add a maximum priority, don't try to raise past this.
// TODO(garretrieger): also try lowering priority of the parent. Make it
// get placed further up in the ordering, closer to it's children.
// this is probably preferable if the total size of the parent object
// is < then the total size of the children (and the parent can be moved).
// Since in that case moving the parent will cause a smaller increase in
// the length of other offsets.
- sorted_graph.raise_childrens_priority (r.parent);
- priority_bumped_parents.add (r.parent);
- resolution_attempted = true;
+ if (sorted_graph.raise_childrens_priority (r.parent)) {
+ priority_bumped_parents.add (r.parent);
+ resolution_attempted = true;
+ }
continue;
}
@@ -1127,19 +1213,17 @@ static bool _process_overflows (const hb_vector_t<graph_t::overflow_record_t>& o
* For a detailed writeup describing how the algorithm operates see:
* docs/repacker.md
*/
-inline void
+inline hb_blob_t*
hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& packed,
hb_tag_t table_tag,
- hb_serialize_context_t* c,
- unsigned max_rounds = 10) {
+ unsigned max_rounds = 20) {
// Kahn sort is ~twice as fast as shortest distance sort and works for many fonts
// so try it first to save time.
graph_t sorted_graph (packed);
sorted_graph.sort_kahn ();
if (!sorted_graph.will_overflow ())
{
- sorted_graph.serialize (c);
- return;
+ return sorted_graph.serialize ();
}
sorted_graph.sort_shortest_distance ();
@@ -1178,17 +1262,17 @@ hb_resolve_overflows (const hb_vector_t<hb_serialize_context_t::object_t *>& pac
if (sorted_graph.in_error ())
{
- c->err (HB_SERIALIZE_ERROR_OTHER);
- return;
+ DEBUG_MSG (SUBSET_REPACK, nullptr, "Sorted graph in error state.");
+ return nullptr;
}
if (sorted_graph.will_overflow ())
{
- c->err (HB_SERIALIZE_ERROR_OFFSET_OVERFLOW);
DEBUG_MSG (SUBSET_REPACK, nullptr, "Offset overflow resolution failed.");
- return;
+ return nullptr;
}
- sorted_graph.serialize (c);
+
+ return sorted_graph.serialize ();
}
#endif /* HB_REPACKER_HH */
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index d22ae06087..823c0be8b5 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -65,19 +65,26 @@ struct hb_serialize_context_t
struct object_t
{
- void fini () { links.fini (); }
+ void fini () {
+ real_links.fini ();
+ virtual_links.fini ();
+ }
bool operator == (const object_t &o) const
{
+ // Virtual links aren't considered for equality since they don't affect the functionality
+ // of the object.
return (tail - head == o.tail - o.head)
- && (links.length == o.links.length)
+ && (real_links.length == o.real_links.length)
&& 0 == hb_memcmp (head, o.head, tail - head)
- && links.as_bytes () == o.links.as_bytes ();
+ && real_links.as_bytes () == o.real_links.as_bytes ();
}
uint32_t hash () const
{
+ // Virtual links aren't considered for equality since they don't affect the functionality
+ // of the object.
return hb_bytes_t (head, tail - head).hash () ^
- links.as_bytes ().hash ();
+ real_links.as_bytes ().hash ();
}
struct link_t
@@ -92,8 +99,14 @@ struct hb_serialize_context_t
char *head;
char *tail;
- hb_vector_t<link_t> links;
+ hb_vector_t<link_t> real_links;
+ hb_vector_t<link_t> virtual_links;
object_t *next;
+
+ auto all_links () const HB_AUTO_RETURN
+ (( hb_concat (this->real_links, this->virtual_links) ));
+ auto all_links_writer () HB_AUTO_RETURN
+ (( hb_concat (this->real_links.writer (), this->virtual_links.writer ()) ));
};
struct snapshot_t
@@ -101,12 +114,14 @@ struct hb_serialize_context_t
char *head;
char *tail;
object_t *current; // Just for sanity check
- unsigned num_links;
+ unsigned num_real_links;
+ unsigned num_virtual_links;
hb_serialize_error_t errors;
};
snapshot_t snapshot ()
- { return snapshot_t { head, tail, current, current->links.length, errors }; }
+ { return snapshot_t {
+ head, tail, current, current->real_links.length, current->virtual_links.length, errors }; }
hb_serialize_context_t (void *start_, unsigned int size) :
start ((char *) start_),
@@ -282,7 +297,8 @@ struct hb_serialize_context_t
if (!len)
{
- assert (!obj->links.length);
+ assert (!obj->real_links.length);
+ assert (!obj->virtual_links.length);
return 0;
}
@@ -292,6 +308,7 @@ struct hb_serialize_context_t
objidx = packed_map.get (obj);
if (objidx)
{
+ merge_virtual_links (obj, objidx);
obj->fini ();
return objidx;
}
@@ -327,7 +344,8 @@ struct hb_serialize_context_t
// Overflows that happened after the snapshot will be erased by the revert.
if (unlikely (in_error () && !only_overflow ())) return;
assert (snap.current == current);
- current->links.shrink (snap.num_links);
+ current->real_links.shrink (snap.num_real_links);
+ current->virtual_links.shrink (snap.num_virtual_links);
errors = snap.errors;
revert (snap.head, snap.tail);
}
@@ -375,8 +393,8 @@ struct hb_serialize_context_t
assert (current);
- auto& link = *current->links.push ();
- if (current->links.in_error ())
+ auto& link = *current->virtual_links.push ();
+ if (current->virtual_links.in_error ())
err (HB_SERIALIZE_ERROR_OTHER);
link.width = 0;
@@ -400,8 +418,8 @@ struct hb_serialize_context_t
assert (current);
assert (current->head <= (const char *) &ofs);
- auto& link = *current->links.push ();
- if (current->links.in_error ())
+ auto& link = *current->real_links.push ();
+ if (current->real_links.in_error ())
err (HB_SERIALIZE_ERROR_OTHER);
link.width = sizeof (T);
@@ -440,10 +458,8 @@ struct hb_serialize_context_t
assert (packed.length > 1);
for (const object_t* parent : ++hb_iter (packed))
- for (const object_t::link_t &link : parent->links)
+ for (const object_t::link_t &link : parent->real_links)
{
- if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets
-
const object_t* child = packed[link.objidx];
if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
unsigned offset = 0;
@@ -642,6 +658,13 @@ struct hb_serialize_context_t
private:
+ void merge_virtual_links (const object_t* from, objidx_t to_idx) {
+ object_t* to = packed[to_idx];
+ for (const auto& l : from->virtual_links) {
+ to->virtual_links.push (l);
+ }
+ }
+
/* Object memory pool. */
hb_pool_t<object_t> object_pool;
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index 53f8664d92..883ab82093 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -248,7 +248,6 @@ static void _colr_closure (hb_face_t *face,
unsigned glyphs_num;
{
glyphs_num = glyphs_colred->get_population ();
-
// Collect all glyphs referenced by COLRv0
hb_set_t glyphset_colrv0;
for (hb_codepoint_t gid : glyphs_colred->iter ())
@@ -397,6 +396,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
_colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset);
_remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
+ hb_set_set (plan->_glyphset_colred, &cur_glyphset);
// Populate a full set of glyphs to retain by adding all referenced
// composite glyphs.
for (hb_codepoint_t gid : cur_glyphset.iter ())
@@ -511,6 +511,7 @@ hb_subset_plan_create (hb_face_t *face,
plan->_glyphset = hb_set_create ();
plan->_glyphset_gsub = hb_set_create ();
plan->_glyphset_mathed = hb_set_create ();
+ plan->_glyphset_colred = hb_set_create ();
plan->codepoint_to_glyph = hb_map_create ();
plan->glyph_map = hb_map_create ();
plan->reverse_glyph_map = hb_map_create ();
@@ -579,6 +580,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
hb_set_destroy (plan->_glyphset);
hb_set_destroy (plan->_glyphset_gsub);
hb_set_destroy (plan->_glyphset_mathed);
+ hb_set_destroy (plan->_glyphset_colred);
hb_map_destroy (plan->gsub_lookups);
hb_map_destroy (plan->gpos_lookups);
hb_map_destroy (plan->gsub_features);
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh
index c0232480bf..b9244e5cb2 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh
@@ -78,6 +78,7 @@ struct hb_subset_plan_t
hb_set_t *_glyphset;
hb_set_t *_glyphset_gsub;
hb_set_t *_glyphset_mathed;
+ hb_set_t *_glyphset_colred;
//active lookups we'd like to retain
hb_map_t *gsub_lookups;
diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc
index 048bdf1888..bb46e5b97f 100644
--- a/thirdparty/harfbuzz/src/hb-subset.cc
+++ b/thirdparty/harfbuzz/src/hb-subset.cc
@@ -104,20 +104,16 @@ _repack (hb_tag_t tag, const hb_serialize_context_t& c)
if (!c.offset_overflow ())
return c.copy_blob ();
- hb_vector_t<char> buf;
- int buf_size = c.end - c.start;
- if (unlikely (!buf.alloc (buf_size)))
- return nullptr;
-
- hb_serialize_context_t repacked ((void *) buf, buf_size);
- hb_resolve_overflows (c.object_graph (), tag, &repacked);
+ hb_blob_t* result = hb_resolve_overflows (c.object_graph (), tag);
- if (unlikely (repacked.in_error ()))
- // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset
- // portion.
+ if (unlikely (!result))
+ {
+ DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c offset overflow resolution failed.",
+ HB_UNTAG (tag));
return nullptr;
+ }
- return repacked.copy_blob ();
+ return result;
}
template<typename TableType>
diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc
index 3dc4c0937d..0e5a114f7d 100644
--- a/thirdparty/harfbuzz/src/hb-uniscribe.cc
+++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc
@@ -878,7 +878,7 @@ retry:
if (backward)
hb_buffer_reverse (buffer);
- buffer->unsafe_to_break_all ();
+ buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
/* Wow, done! */
return true;
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index c9fefa1df6..52b124b745 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 1
+#define HB_VERSION_MINOR 2
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 2
+#define HB_VERSION_MICRO 0
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "3.1.2"
+#define HB_VERSION_STRING "3.2.0"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h
index dc5ae199ca..e280dbb1c6 100644
--- a/thirdparty/mbedtls/include/mbedtls/aes.h
+++ b/thirdparty/mbedtls/include/mbedtls/aes.h
@@ -22,13 +22,7 @@
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -41,37 +35,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_AES_H
#define MBEDTLS_AES_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
+#include "mbedtls/platform_util.h"
#include <stddef.h>
#include <stdint.h>
@@ -201,6 +175,7 @@ void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx );
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
@@ -219,6 +194,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits );
@@ -239,6 +215,7 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
@@ -259,6 +236,7 @@ int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
* \return \c 0 on success.
* \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits );
@@ -287,6 +265,7 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
@@ -334,6 +313,7 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
* \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
* on failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
int mode,
size_t length,
@@ -378,6 +358,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
* smaller than an AES block in size (16 Bytes) or if \p
* length is larger than 2^20 blocks (16 MiB).
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
@@ -426,6 +407,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
int mode,
size_t length,
@@ -470,6 +452,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
int mode,
size_t length,
@@ -524,6 +507,7 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
@@ -606,6 +590,7 @@ int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
@@ -626,6 +611,7 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
@@ -641,6 +627,7 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
*
* \return \c 0 on success.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] );
@@ -690,6 +677,7 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
* \return \c 0 on success.
* \return \c 1 on failure.
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_aes_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h
index 9b63a0010a..c1d22f59af 100644
--- a/thirdparty/mbedtls/include/mbedtls/aesni.h
+++ b/thirdparty/mbedtls/include/mbedtls/aesni.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -27,38 +21,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_AESNI_H
#define MBEDTLS_AESNI_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "aes.h"
+#include "mbedtls/aes.h"
#define MBEDTLS_AESNI_AES 0x02000000u
#define MBEDTLS_AESNI_CLMUL 0x00000002u
diff --git a/thirdparty/mbedtls/include/mbedtls/arc4.h b/thirdparty/mbedtls/include/mbedtls/arc4.h
index cfe3aea96a..f4b0f9f350 100644
--- a/thirdparty/mbedtls/include/mbedtls/arc4.h
+++ b/thirdparty/mbedtls/include/mbedtls/arc4.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,33 +22,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
#ifndef MBEDTLS_ARC4_H
#define MBEDTLS_ARC4_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/aria.h b/thirdparty/mbedtls/include/mbedtls/aria.h
index 50bbc82c13..226e2dbf3c 100644
--- a/thirdparty/mbedtls/include/mbedtls/aria.h
+++ b/thirdparty/mbedtls/include/mbedtls/aria.h
@@ -11,13 +11,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -30,34 +24,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ARIA_H
#define MBEDTLS_ARIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -65,7 +38,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
#define MBEDTLS_ARIA_ENCRYPT 1 /**< ARIA encryption. */
#define MBEDTLS_ARIA_DECRYPT 0 /**< ARIA decryption. */
diff --git a/thirdparty/mbedtls/include/mbedtls/asn1.h b/thirdparty/mbedtls/include/mbedtls/asn1.h
index 1fa7bfaf3c..10f7905b7e 100644
--- a/thirdparty/mbedtls/include/mbedtls/asn1.h
+++ b/thirdparty/mbedtls/include/mbedtls/asn1.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ASN1_H
#define MBEDTLS_ASN1_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -58,7 +31,7 @@
#include <stddef.h>
#if defined(MBEDTLS_BIGNUM_C)
-#include "bignum.h"
+#include "mbedtls/bignum.h"
#endif
/**
@@ -81,7 +54,7 @@
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064
/** Actual length differs from expected length. */
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066
-/** Data is invalid. (not used) */
+/** Data is invalid. */
#define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068
/** Memory allocation failed */
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A
@@ -107,6 +80,7 @@
#define MBEDTLS_ASN1_OCTET_STRING 0x04
#define MBEDTLS_ASN1_NULL 0x05
#define MBEDTLS_ASN1_OID 0x06
+#define MBEDTLS_ASN1_ENUMERATED 0x0A
#define MBEDTLS_ASN1_UTF8_STRING 0x0C
#define MBEDTLS_ASN1_SEQUENCE 0x10
#define MBEDTLS_ASN1_SET 0x11
@@ -121,6 +95,18 @@
#define MBEDTLS_ASN1_CONSTRUCTED 0x20
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
+/* Slightly smaller way to check if tag is a string tag
+ * compared to canonical implementation. */
+#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \
+ ( ( tag ) < 32u && ( \
+ ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_T61_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \
+ ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) )
+
/*
* Bit masks for each of the components of an ASN.1 tag as specified in
* ITU X.690 (08/2015), section 8.1 "General rules for encoding",
@@ -151,6 +137,10 @@
( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
+#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \
+ ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \
+ memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 )
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -208,119 +198,342 @@ mbedtls_asn1_named_data;
* \brief Get the length of an ASN.1 element.
* Updates the pointer to immediately behind the length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the value
- *
- * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
- * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
- * unparseable.
+ * \param p On entry, \c *p points to the first byte of the length,
+ * i.e. immediately after the tag.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_len( unsigned char **p,
- const unsigned char *end,
- size_t *len );
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Get the tag and length of the tag. Check for the requested tag.
+ * \brief Get the tag and length of the element.
+ * Check for the requested tag.
* Updates the pointer to immediately behind the tag and length.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len The variable that will receive the length
- * \param tag The expected tag
- *
- * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
- * not match requested tag, or another specific ASN.1 error code.
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ * \param tag The expected tag.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start
+ * with the requested tag.
+ * \return #MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element
+ * would end beyond \p end.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparseable.
*/
int mbedtls_asn1_get_tag( unsigned char **p,
- const unsigned char *end,
- size_t *len, int tag );
+ const unsigned char *end,
+ size_t *len, int tag );
/**
* \brief Retrieve a boolean ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value (\c 0 or \c 1).
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BOOLEAN.
*/
int mbedtls_asn1_get_bool( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
/**
* \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param val The variable that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 error code.
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
+ *
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
*/
int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val );
+ const unsigned char *end,
+ int *val );
/**
- * \brief Retrieve a bitstring ASN.1 tag and its value.
+ * \brief Retrieve an enumerated ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param bs The variable that will receive the value
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
+ *
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 ENUMERATED.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ */
+int mbedtls_asn1_get_enum( unsigned char **p,
+ const unsigned char *end,
+ int *val );
+
+/**
+ * \brief Retrieve a bitstring ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
*
- * \return 0 if successful or a specific ASN.1 error code.
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param bs On success, ::mbedtls_asn1_bitstring information about
+ * the parsed value.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid BIT STRING.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
- mbedtls_asn1_bitstring *bs);
+ mbedtls_asn1_bitstring *bs );
/**
* \brief Retrieve a bitstring ASN.1 tag without unused bits and its
* value.
* Updates the pointer to the beginning of the bit/octet string.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param len Length of the actual bit/octect string in bytes
- *
- * \return 0 if successful or a specific ASN.1 error code.
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * of the content of the BIT STRING.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On success, \c *len is the length of the content in bytes.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with
+ * a valid BIT STRING with a nonzero number of unused bits.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 BIT STRING.
*/
-int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len );
+int mbedtls_asn1_get_bitstring_null( unsigned char **p,
+ const unsigned char *end,
+ size_t *len );
/**
- * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- * Updated the pointer to immediately behind the full sequence tag.
- *
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param cur First variable in the chain to fill
- * \param tag Type of sequence
- *
- * \return 0 if successful or a specific ASN.1 error code.
+ * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>".
+ * Updates the pointer to immediately behind the full sequence tag.
+ *
+ * This function allocates memory for the sequence elements. You can free
+ * the allocated memory with mbedtls_asn1_sequence_free().
+ *
+ * \note On error, this function may return a partial list in \p cur.
+ * You must set `cur->next = NULL` before calling this function!
+ * Otherwise it is impossible to distinguish a previously non-null
+ * pointer from a pointer to an object allocated by this function.
+ *
+ * \note If the sequence is empty, this function does not modify
+ * \c *cur. If the sequence is valid and non-empty, this
+ * function sets `cur->buf.tag` to \p tag. This allows
+ * callers to distinguish between an empty sequence and
+ * a one-element sequence.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p is equal to \p end.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param cur A ::mbedtls_asn1_sequence which this function fills.
+ * When this function returns, \c *cur is the head of a linked
+ * list. Each node in this list is allocated with
+ * mbedtls_calloc() apart from \p cur itself, and should
+ * therefore be freed with mbedtls_free().
+ * The list describes the content of the sequence.
+ * The head of the list (i.e. \c *cur itself) describes the
+ * first element, `*cur->next` describes the second element, etc.
+ * For each element, `buf.tag == tag`, `buf.len` is the length
+ * of the content of the content of the element, and `buf.p`
+ * points to the first byte of the content (i.e. immediately
+ * past the length of the element).
+ * Note that list elements may be allocated even on error.
+ * \param tag Each element of the sequence must have this tag.
+ *
+ * \return 0 if successful.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains
+ * extra data after a valid SEQUENCE OF \p tag.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with
+ * an ASN.1 SEQUENCE in which an element has a tag that
+ * is different from \p tag.
+ * \return #MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 SEQUENCE.
*/
int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag);
+ const unsigned char *end,
+ mbedtls_asn1_sequence *cur,
+ int tag );
+/**
+ * \brief Free a heap-allocated linked list presentation of
+ * an ASN.1 sequence, including the first element.
+ *
+ * There are two common ways to manage the memory used for the representation
+ * of a parsed ASN.1 sequence:
+ * - Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc().
+ * Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head`.
+ * - Allocate a head node `mbedtls_asn1_sequence *head` in any manner,
+ * for example on the stack. Make sure that `head->next == NULL`.
+ * Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of().
+ * When you have finished processing the sequence,
+ * call mbedtls_asn1_sequence_free() on `head->cur`,
+ * then free `head` itself in the appropriate manner.
+ *
+ * \param seq The address of the first sequence component. This may
+ * be \c NULL, in which case this functions returns
+ * immediately.
+ */
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq );
+
+/**
+ * \brief Traverse an ASN.1 SEQUENCE container and
+ * call a callback for each entry.
+ *
+ * This function checks that the input is a SEQUENCE of elements that
+ * each have a "must" tag, and calls a callback function on the elements
+ * that have a "may" tag.
+ *
+ * For example, to validate that the input is a SEQUENCE of `tag1` and call
+ * `cb` on each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xff, tag1, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of ANY and call `cb` on
+ * each element, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0, 0, 0, 0, cb, ctx);
+ * ```
+ *
+ * To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING}
+ * and call `cb` on each element that is an OCTET STRING, use
+ * ```
+ * mbedtls_asn1_traverse_sequence_of(&p, end, 0xfe, 0x04, 0xff, 0x04, cb, ctx);
+ * ```
+ *
+ * The callback is called on the elements with a "may" tag from left to
+ * right. If the input is not a valid SEQUENCE of elements with a "must" tag,
+ * the callback is called on the elements up to the leftmost point where
+ * the input is invalid.
+ *
+ * \warning This function is still experimental and may change
+ * at any time.
+ *
+ * \param p The address of the pointer to the beginning of
+ * the ASN.1 SEQUENCE header. This is updated to
+ * point to the end of the ASN.1 SEQUENCE container
+ * on a successful invocation.
+ * \param end The end of the ASN.1 SEQUENCE container.
+ * \param tag_must_mask A mask to be applied to the ASN.1 tags found within
+ * the SEQUENCE before comparing to \p tag_must_value.
+ * \param tag_must_val The required value of each ASN.1 tag found in the
+ * SEQUENCE, after masking with \p tag_must_mask.
+ * Mismatching tags lead to an error.
+ * For example, a value of \c 0 for both \p tag_must_mask
+ * and \p tag_must_val means that every tag is allowed,
+ * while a value of \c 0xFF for \p tag_must_mask means
+ * that \p tag_must_val is the only allowed tag.
+ * \param tag_may_mask A mask to be applied to the ASN.1 tags found within
+ * the SEQUENCE before comparing to \p tag_may_value.
+ * \param tag_may_val The desired value of each ASN.1 tag found in the
+ * SEQUENCE, after masking with \p tag_may_mask.
+ * Mismatching tags will be silently ignored.
+ * For example, a value of \c 0 for \p tag_may_mask and
+ * \p tag_may_val means that any tag will be considered,
+ * while a value of \c 0xFF for \p tag_may_mask means
+ * that all tags with value different from \p tag_may_val
+ * will be ignored.
+ * \param cb The callback to trigger for each component
+ * in the ASN.1 SEQUENCE that matches \p tag_may_val.
+ * The callback function is called with the following
+ * parameters:
+ * - \p ctx.
+ * - The tag of the current element.
+ * - A pointer to the start of the current element's
+ * content inside the input.
+ * - The length of the content of the current element.
+ * If the callback returns a non-zero value,
+ * the function stops immediately,
+ * forwarding the callback's return value.
+ * \param ctx The context to be passed to the callback \p cb.
+ *
+ * \return \c 0 if successful the entire ASN.1 SEQUENCE
+ * was traversed without parsing or callback errors.
+ * \return #MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input
+ * contains extra data after a valid SEQUENCE
+ * of elements with an accepted tag.
+ * \return #MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts
+ * with an ASN.1 SEQUENCE in which an element has a tag
+ * that is not accepted.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 SEQUENCE.
+ * \return A non-zero error code forwarded from the callback
+ * \p cb in case the latter returns a non-zero value.
+ */
+int mbedtls_asn1_traverse_sequence_of(
+ unsigned char **p,
+ const unsigned char *end,
+ unsigned char tag_must_mask, unsigned char tag_must_val,
+ unsigned char tag_may_mask, unsigned char tag_may_val,
+ int (*cb)( void *ctx, int tag,
+ unsigned char* start, size_t len ),
+ void *ctx );
#if defined(MBEDTLS_BIGNUM_C)
/**
- * \brief Retrieve a MPI value from an integer ASN.1 tag.
+ * \brief Retrieve an integer ASN.1 tag and its value.
* Updates the pointer to immediately behind the full tag.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param X The MPI that will receive the value
- *
- * \return 0 if successful or a specific ASN.1 or MPI error code.
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param X On success, the parsed value.
+ *
+ * \return 0 if successful.
+ * \return An ASN.1 error code if the input does not start with
+ * a valid ASN.1 INTEGER.
+ * \return #MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does
+ * not fit in an \c int.
+ * \return An MPI error code if the parsed value is too large.
*/
int mbedtls_asn1_get_mpi( unsigned char **p,
- const unsigned char *end,
- mbedtls_mpi *X );
+ const unsigned char *end,
+ mbedtls_mpi *X );
#endif /* MBEDTLS_BIGNUM_C */
/**
@@ -328,10 +541,14 @@ int mbedtls_asn1_get_mpi( unsigned char **p,
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
- * \param params The buffer to receive the params (if any)
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
+ * \param params The buffer to receive the parameters.
+ * This is zeroized if there are no parameters.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -345,9 +562,12 @@ int mbedtls_asn1_get_alg( unsigned char **p,
* Updates the pointer to immediately behind the full
* AlgorithmIdentifier.
*
- * \param p The position in the ASN.1 data
- * \param end End of data
- * \param alg The buffer to receive the OID
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the AlgorithmIdentifier element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param alg The buffer to receive the OID.
*
* \return 0 if successful or a specific ASN.1 or MPI error code.
*/
@@ -371,15 +591,19 @@ mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *
/**
* \brief Free a mbedtls_asn1_named_data entry
*
- * \param entry The named data entry to free
+ * \param entry The named data entry to free.
+ * This function calls mbedtls_free() on
+ * `entry->oid.p` and `entry->val.p`.
*/
void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
/**
- * \brief Free all entries in a mbedtls_asn1_named_data list
- * Head will be set to NULL
+ * \brief Free all entries in a mbedtls_asn1_named_data list.
*
- * \param head Pointer to the head of the list of named data entries to free
+ * \param head Pointer to the head of the list of named data entries to free.
+ * This function calls mbedtls_asn1_free_named_data() and
+ * mbedtls_free() on each list element and
+ * sets \c *head to \c NULL.
*/
void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
diff --git a/thirdparty/mbedtls/include/mbedtls/asn1write.h b/thirdparty/mbedtls/include/mbedtls/asn1write.h
index 3c7cdd6b46..44afae0e56 100644
--- a/thirdparty/mbedtls/include/mbedtls/asn1write.h
+++ b/thirdparty/mbedtls/include/mbedtls/asn1write.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,38 +18,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ASN1_WRITE_H
#define MBEDTLS_ASN1_WRITE_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "asn1.h"
+#include "mbedtls/asn1.h"
#define MBEDTLS_ASN1_CHK_ADD(g, f) \
do \
@@ -125,6 +98,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param X The MPI to write.
+ * It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
@@ -209,6 +183,7 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
* \param p The reference to the current position pointer.
* \param start The start of the buffer, for bounds-checking.
* \param val The integer value to write.
+ * It must be non-negative.
*
* \return The number of bytes written to \p p on success.
* \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
@@ -216,6 +191,21 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start,
int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val );
/**
+ * \brief Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value
+ * in ASN.1 format.
+ *
+ * \note This function works backwards in data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer, for bounds-checking.
+ * \param val The integer value to write.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
+ */
+int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val );
+
+/**
* \brief Write a string in ASN.1 format using a specific
* string encoding tag.
@@ -257,7 +247,7 @@ int mbedtls_asn1_write_printable_string( unsigned char **p,
/**
* \brief Write a UTF8 string in ASN.1 format using the UTF8String
- * string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
+ * string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
*
* \note This function works backwards in data buffer.
*
@@ -309,6 +299,28 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits );
/**
+ * \brief This function writes a named bitstring tag
+ * (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format.
+ *
+ * As stated in RFC 5280 Appendix B, trailing zeroes are
+ * omitted when encoding named bitstrings in DER.
+ *
+ * \note This function works backwards within the data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer which is used for bounds-checking.
+ * \param buf The bitstring to write.
+ * \param bits The total number of bits in the bitstring.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_asn1_write_named_bitstring( unsigned char **p,
+ unsigned char *start,
+ const unsigned char *buf,
+ size_t bits );
+
+/**
* \brief Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
* and value in ASN.1 format.
*
@@ -335,9 +347,13 @@ int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
* through (will be updated in case of a new entry).
* \param oid The OID to look for.
* \param oid_len The size of the OID.
- * \param val The data to store (can be \c NULL if you want to fill
- * it by hand).
+ * \param val The associated data to store. If this is \c NULL,
+ * no data is copied to the new or existing buffer.
* \param val_len The minimum length of the data buffer needed.
+ * If this is 0, do not allocate a buffer for the associated
+ * data.
+ * If the OID was already present, enlarge, shrink or free
+ * the existing buffer to fit \p val_len.
*
* \return A pointer to the new / existing entry on success.
* \return \c NULL if if there was a memory allocation error.
diff --git a/thirdparty/mbedtls/include/mbedtls/base64.h b/thirdparty/mbedtls/include/mbedtls/base64.h
index eaada6e92e..cf4149e731 100644
--- a/thirdparty/mbedtls/include/mbedtls/base64.h
+++ b/thirdparty/mbedtls/include/mbedtls/base64.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_BASE64_H
#define MBEDTLS_BASE64_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h
index f7b86cb50e..9d2cff3275 100644
--- a/thirdparty/mbedtls/include/mbedtls/bignum.h
+++ b/thirdparty/mbedtls/include/mbedtls/bignum.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_BIGNUM_H
#define MBEDTLS_BIGNUM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -162,7 +135,8 @@
defined(__ppc64__) || defined(__powerpc64__) || \
defined(__ia64__) || defined(__alpha__) || \
( defined(__sparc__) && defined(__arch64__) ) || \
- defined(__s390x__) || defined(__mips64) )
+ defined(__s390x__) || defined(__mips64) || \
+ defined(__aarch64__) )
#if !defined(MBEDTLS_HAVE_INT64)
#define MBEDTLS_HAVE_INT64
#endif /* MBEDTLS_HAVE_INT64 */
@@ -528,8 +502,24 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf,
size_t buflen );
/**
- * \brief Export an MPI into unsigned big endian binary data
- * of fixed size.
+ * \brief Import X from unsigned binary data, little endian
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param buf The input buffer. This must be a readable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The length of the input buffer \p p in Bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian.
+ * Always fills the whole buffer, which will start with zeros
+ * if the number is smaller.
*
* \param X The source MPI. This must point to an initialized MPI.
* \param buf The output buffer. This must be a writable buffer of length
@@ -545,6 +535,24 @@ int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf,
size_t buflen );
/**
+ * \brief Export X into unsigned binary data, little endian.
+ * Always fills the whole buffer, which will end with zeros
+ * if the number is smaller.
+ *
+ * \param X The source MPI. This must point to an initialized MPI.
+ * \param buf The output buffer. This must be a writable buffer of length
+ * \p buflen Bytes.
+ * \param buflen The size of the output buffer \p buf in Bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't
+ * large enough to hold the value of \p X.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen );
+
+/**
* \brief Perform a left-shift on an MPI: X <<= count
*
* \param X The MPI to shift. This must point to an initialized MPI.
@@ -871,6 +879,44 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
+/** Generate a random number uniformly in a range.
+ *
+ * This function generates a random number between \p min inclusive and
+ * \p N exclusive.
+ *
+ * The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)
+ * when the RNG is a suitably parametrized instance of HMAC_DRBG
+ * and \p min is \c 1.
+ *
+ * \note There are `N - min` possible outputs. The lower bound
+ * \p min can be reached, but the upper bound \p N cannot.
+ *
+ * \param X The destination MPI. This must point to an initialized MPI.
+ * \param min The minimum value to return.
+ * It must be nonnegative.
+ * \param N The upper bound of the range, exclusive.
+ * In other words, this is one plus the maximum value to return.
+ * \p N must be strictly larger than \p min.
+ * \param f_rng The RNG function to use. This must not be \c NULL.
+ * \param p_rng The RNG parameter to be passed to \p f_rng.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if a memory allocation failed.
+ * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p min or \p N is invalid
+ * or if they are incompatible.
+ * \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was
+ * unable to find a suitable value within a limited number
+ * of attempts. This has a negligible probability if \p N
+ * is significantly larger than \p min, which is the case
+ * for all usual cryptographic applications.
+ * \return Another negative error code on failure.
+ */
+int mbedtls_mpi_random( mbedtls_mpi *X,
+ mbedtls_mpi_sint min,
+ const mbedtls_mpi *N,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
/**
* \brief Compute the greatest common divisor: G = gcd(A, B)
*
diff --git a/thirdparty/mbedtls/include/mbedtls/blowfish.h b/thirdparty/mbedtls/include/mbedtls/blowfish.h
index 86f7ce7bf2..77dca70d31 100644
--- a/thirdparty/mbedtls/include/mbedtls/blowfish.h
+++ b/thirdparty/mbedtls/include/mbedtls/blowfish.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_BLOWFISH_H
#define MBEDTLS_BLOWFISH_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -58,7 +31,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
#define MBEDTLS_BLOWFISH_ENCRYPT 1
#define MBEDTLS_BLOWFISH_DECRYPT 0
diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
index f84f9650dd..31137cd4c2 100644
--- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h
+++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,27 +18,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* Multiply source vector [s] with b, add result
@@ -64,12 +37,12 @@
#define MBEDTLS_BN_MUL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
+#include "mbedtls/bignum.h"
/*
@@ -263,6 +236,30 @@
#endif /* AMD64 */
+#if defined(__aarch64__)
+
+#define MULADDC_INIT \
+ asm(
+
+#define MULADDC_CORE \
+ "ldr x4, [%2], #8 \n\t" \
+ "ldr x5, [%1] \n\t" \
+ "mul x6, x4, %4 \n\t" \
+ "umulh x7, x4, %4 \n\t" \
+ "adds x5, x5, x6 \n\t" \
+ "adc x7, x7, xzr \n\t" \
+ "adds x5, x5, %0 \n\t" \
+ "adc %0, x7, xzr \n\t" \
+ "str x5, [%1], #8 \n\t"
+
+#define MULADDC_STOP \
+ : "+r" (c), "+r" (d), "+r" (s), "+m" (*(uint64_t (*)[16]) d) \
+ : "r" (b), "m" (*(const uint64_t (*)[16]) s) \
+ : "x4", "x5", "x6", "x7", "cc" \
+ );
+
+#endif /* Aarch64 */
+
#if defined(__mc68020__) || defined(__mcpu32__)
#define MULADDC_INIT \
diff --git a/thirdparty/mbedtls/include/mbedtls/camellia.h b/thirdparty/mbedtls/include/mbedtls/camellia.h
index fe5ac3721f..925a623e47 100644
--- a/thirdparty/mbedtls/include/mbedtls/camellia.h
+++ b/thirdparty/mbedtls/include/mbedtls/camellia.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CAMELLIA_H
#define MBEDTLS_CAMELLIA_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -58,7 +31,7 @@
#include <stddef.h>
#include <stdint.h>
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
#define MBEDTLS_CAMELLIA_ENCRYPT 1
#define MBEDTLS_CAMELLIA_DECRYPT 0
diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h
index 78c0ea42bc..ece5a901cb 100644
--- a/thirdparty/mbedtls/include/mbedtls/ccm.h
+++ b/thirdparty/mbedtls/include/mbedtls/ccm.h
@@ -29,13 +29,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -48,39 +42,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CCM_H
#define MBEDTLS_CCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "cipher.h"
+#include "mbedtls/cipher.h"
/** Bad input parameters to the function. */
#define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D
diff --git a/thirdparty/mbedtls/include/mbedtls/certs.h b/thirdparty/mbedtls/include/mbedtls/certs.h
index 8472a6f38c..c93c741c7f 100644
--- a/thirdparty/mbedtls/include/mbedtls/certs.h
+++ b/thirdparty/mbedtls/include/mbedtls/certs.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CERTS_H
#define MBEDTLS_CERTS_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/chacha20.h b/thirdparty/mbedtls/include/mbedtls/chacha20.h
index f4073e382c..03b4871478 100644
--- a/thirdparty/mbedtls/include/mbedtls/chacha20.h
+++ b/thirdparty/mbedtls/include/mbedtls/chacha20.h
@@ -14,13 +14,7 @@
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -33,34 +27,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CHACHA20_H
#define MBEDTLS_CHACHA20_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/chachapoly.h b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
index 436d1739f7..c4ec7b5f2a 100644
--- a/thirdparty/mbedtls/include/mbedtls/chachapoly.h
+++ b/thirdparty/mbedtls/include/mbedtls/chachapoly.h
@@ -14,13 +14,7 @@
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -33,40 +27,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CHACHAPOLY_H
#define MBEDTLS_CHACHAPOLY_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
/* for shared error codes */
-#include "poly1305.h"
+#include "mbedtls/poly1305.h"
/** The requested operation is not permitted in the current state. */
#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054
@@ -86,7 +59,7 @@ mbedtls_chachapoly_mode_t;
#if !defined(MBEDTLS_CHACHAPOLY_ALT)
-#include "chacha20.h"
+#include "mbedtls/chacha20.h"
typedef struct mbedtls_chachapoly_context
{
diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h
index b150b815fc..396fe7dfc2 100644
--- a/thirdparty/mbedtls/include/mbedtls/check_config.h
+++ b/thirdparty/mbedtls/include/mbedtls/check_config.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,27 +18,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -70,16 +43,20 @@
#endif
/* Fix the config here. Not convenient to put an #ifdef _WIN32 in config.h as
- * it would confuse config.pl. */
+ * it would confuse config.py. */
#if !defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) && \
!defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO)
#define MBEDTLS_PLATFORM_SNPRINTF_ALT
#endif
+
+#if !defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT) && \
+ !defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
+#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
+#endif
#endif /* _WIN32 */
-#if defined(TARGET_LIKE_MBED) && \
- ( defined(MBEDTLS_NET_C) || defined(MBEDTLS_TIMING_C) )
-#error "The NET and TIMING modules are not available for mbed OS - please use the network and timing functions provided by mbed OS"
+#if defined(TARGET_LIKE_MBED) && defined(MBEDTLS_NET_C)
+#error "The NET module is not available for mbed OS - please use the network functions provided by Mbed OS"
#endif
#if defined(MBEDTLS_DEPRECATED_WARNING) && \
@@ -123,6 +100,17 @@
#if defined(MBEDTLS_ECDSA_C) && \
( !defined(MBEDTLS_ECP_C) || \
+ !( defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) ) || \
!defined(MBEDTLS_ASN1_PARSE_C) || \
!defined(MBEDTLS_ASN1_WRITE_C) )
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
@@ -134,14 +122,25 @@
#endif
#if defined(MBEDTLS_ECP_RESTARTABLE) && \
- ( defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
+ ( defined(MBEDTLS_USE_PSA_CRYPTO) || \
+ defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) || \
defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || \
defined(MBEDTLS_ECDSA_SIGN_ALT) || \
defined(MBEDTLS_ECDSA_VERIFY_ALT) || \
defined(MBEDTLS_ECDSA_GENKEY_ALT) || \
defined(MBEDTLS_ECP_INTERNAL_ALT) || \
defined(MBEDTLS_ECP_ALT) )
-#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative ECP implementation"
+#error "MBEDTLS_ECP_RESTARTABLE defined, but it cannot coexist with an alternative or PSA-based ECP implementation"
+#endif
+
+#if defined(MBEDTLS_ECP_RESTARTABLE) && \
+ ! defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+#error "MBEDTLS_ECP_RESTARTABLE defined, but not MBEDTLS_ECDH_LEGACY_CONTEXT"
+#endif
+
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED) && \
+ defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+#error "MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED defined, but MBEDTLS_ECDH_LEGACY_CONTEXT not disabled"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
@@ -169,10 +168,8 @@
defined(MBEDTLS_ECP_ALT) || \
defined(MBEDTLS_CTR_DRBG_C) || \
defined(MBEDTLS_HMAC_DRBG_C) || \
- defined(MBEDTLS_SHA512_C) || \
- defined(MBEDTLS_SHA256_C) || \
defined(MBEDTLS_ECP_NO_INTERNAL_RNG))
-#error "MBEDTLS_ECP_C requires a DRBG or SHA-2 module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used"
+#error "MBEDTLS_ECP_C requires a DRBG module unless MBEDTLS_ECP_NO_INTERNAL_RNG is defined or an alternative implementation is used"
#endif
#if defined(MBEDTLS_PK_PARSE_C) && !defined(MBEDTLS_ASN1_PARSE_C)
@@ -218,7 +215,7 @@
#endif
#if defined(MBEDTLS_GCM_C) && ( \
- !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
+ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
@@ -254,6 +251,10 @@
#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && !defined(MBEDTLS_ECP_INTERNAL_ALT)
+#error "MBEDTLS_ECP_NO_FALLBACK defined, but no alternative implementation enabled"
+#endif
+
#if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C)
#error "MBEDTLS_HAVEGE_C defined, but not all prerequisites"
#endif
@@ -267,12 +268,14 @@
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \
- ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+ ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) || \
+ !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) )
+ ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_RSA_C) || \
+ !defined(MBEDTLS_X509_CRT_PARSE_C) )
#error "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites"
#endif
@@ -321,6 +324,14 @@
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
+ ( !defined(MBEDTLS_SHA256_C) && \
+ !defined(MBEDTLS_SHA512_C) && \
+ !defined(MBEDTLS_SHA1_C) )
+#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
+#endif
+
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
@@ -363,6 +374,14 @@
#error "MBEDTLS_PKCS11_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_PKCS11_C)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_PKCS11_C is deprecated and will be removed in a future version of Mbed TLS"
+#endif
+#endif /* MBEDTLS_PKCS11_C */
+
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_EXIT_ALT defined, but not all prerequisites"
#endif
@@ -552,6 +571,54 @@
#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously"
#endif
+#if defined(MBEDTLS_PSA_CRYPTO_C) && \
+ !( ( ( defined(MBEDTLS_CTR_DRBG_C) || defined(MBEDTLS_HMAC_DRBG_C) ) && \
+ defined(MBEDTLS_ENTROPY_C) ) || \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) )
+#error "MBEDTLS_PSA_CRYPTO_C defined, but not all prerequisites (missing RNG)"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_SPM) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_PSA_CRYPTO_SPM defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C) && \
+ ! ( defined(MBEDTLS_PSA_CRYPTO_C) && \
+ defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) )
+#error "MBEDTLS_PSA_CRYPTO_SE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
+ ! defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_PSA_CRYPTO_STORAGE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ !( defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) && \
+ defined(MBEDTLS_ENTROPY_NV_SEED) )
+#error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources"
+#endif
+
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \
+ defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG"
+#endif
+
+#if defined(MBEDTLS_PSA_ITS_FILE_C) && \
+ !defined(MBEDTLS_FS_IO)
+#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+#error "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER defined, but it cannot coexist with MBEDTLS_USE_PSA_CRYPTO."
+#endif
+
#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites"
@@ -567,6 +634,10 @@
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_SHA512_NO_SHA384) && !defined(MBEDTLS_SHA512_C)
+#error "MBEDTLS_SHA512_NO_SHA384 defined without MBEDTLS_SHA512_C"
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_SSL3) && ( !defined(MBEDTLS_MD5_C) || \
!defined(MBEDTLS_SHA1_C) )
#error "MBEDTLS_SSL_PROTO_SSL3 defined, but not all prerequisites"
@@ -587,6 +658,11 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL) && ( !defined(MBEDTLS_HKDF_C) && \
+ !defined(MBEDTLS_SHA256_C) && !defined(MBEDTLS_SHA512_C) )
+#error "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL defined, but not all prerequisites"
+#endif
+
#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
!(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
@@ -659,6 +735,23 @@
#error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
+ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
+ defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \
+ MBEDTLS_SSL_CID_IN_LEN_MAX > 255
+#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)"
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \
+ defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \
+ MBEDTLS_SSL_CID_OUT_LEN_MAX > 255
+#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)"
+#endif
+
#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \
( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) )
#error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites"
@@ -711,6 +804,10 @@
#endif
#undef MBEDTLS_THREADING_IMPL
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && !defined(MBEDTLS_PSA_CRYPTO_C)
+#error "MBEDTLS_USE_PSA_CRYPTO defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_VERSION_FEATURES) && !defined(MBEDTLS_VERSION_C)
#error "MBEDTLS_VERSION_FEATURES defined, but not all prerequisites"
#endif
@@ -760,6 +857,38 @@
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_SSL_PROTO_SSL3 is deprecated and will be removed in a future version of Mbed TLS"
+#endif
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO is deprecated and will be removed in a future version of Mbed TLS"
+#endif
+#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+#error "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
+#elif defined(MBEDTLS_DEPRECATED_WARNING)
+#warning "MBEDTLS_SSL_HW_RECORD_ACCEL is deprecated and will be removed in a future version of Mbed TLS"
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+#if defined(MBEDTLS_SSL_DTLS_SRTP) && ( !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_DTLS_SRTP defined, but not all prerequisites"
+#endif
+
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH) && ( !defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) )
+#error "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH defined, but not all prerequisites"
+#endif
+
/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
diff --git a/thirdparty/mbedtls/include/mbedtls/cipher.h b/thirdparty/mbedtls/include/mbedtls/cipher.h
index f485b17d8d..6d83da8827 100644
--- a/thirdparty/mbedtls/include/mbedtls/cipher.h
+++ b/thirdparty/mbedtls/include/mbedtls/cipher.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,40 +22,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CIPHER_H
#define MBEDTLS_CIPHER_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
-#include "platform_util.h"
+#include "mbedtls/platform_util.h"
#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
#define MBEDTLS_CIPHER_MODE_AEAD
@@ -209,21 +182,29 @@ typedef enum {
MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */
MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */
MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */
+ MBEDTLS_CIPHER_AES_128_KW, /**< AES cipher with 128-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_192_KW, /**< AES cipher with 192-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_256_KW, /**< AES cipher with 256-bit NIST KW mode. */
+ MBEDTLS_CIPHER_AES_128_KWP, /**< AES cipher with 128-bit NIST KWP mode. */
+ MBEDTLS_CIPHER_AES_192_KWP, /**< AES cipher with 192-bit NIST KWP mode. */
+ MBEDTLS_CIPHER_AES_256_KWP, /**< AES cipher with 256-bit NIST KWP mode. */
} mbedtls_cipher_type_t;
/** Supported cipher modes. */
typedef enum {
- MBEDTLS_MODE_NONE = 0, /**< None. */
- MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
- MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
- MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
- MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
- MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
- MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
- MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
- MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
- MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
+ MBEDTLS_MODE_NONE = 0, /**< None. */
+ MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */
+ MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */
+ MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */
+ MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */
+ MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */
+ MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */
+ MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */
+ MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */
+ MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */
MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */
+ MBEDTLS_MODE_KW, /**< The SP800-38F KW mode */
+ MBEDTLS_MODE_KWP, /**< The SP800-38F KWP mode */
} mbedtls_cipher_mode_t;
/** Supported cipher padding types. */
@@ -254,10 +235,30 @@ enum {
};
/** Maximum length of any IV, in Bytes. */
+/* This should ideally be derived automatically from list of ciphers.
+ * This should be kept in sync with MBEDTLS_SSL_MAX_IV_LENGTH defined
+ * in ssl_internal.h. */
#define MBEDTLS_MAX_IV_LENGTH 16
+
/** Maximum block size of any cipher, in Bytes. */
+/* This should ideally be derived automatically from list of ciphers.
+ * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
+ * in ssl_internal.h. */
#define MBEDTLS_MAX_BLOCK_LENGTH 16
+/** Maximum key length, in Bytes. */
+/* This should ideally be derived automatically from list of ciphers.
+ * For now, only check whether XTS is enabled which uses 64 Byte keys,
+ * and use 32 Bytes as an upper bound for the maximum key length otherwise.
+ * This should be kept in sync with MBEDTLS_SSL_MAX_BLOCK_LENGTH defined
+ * in ssl_internal.h, which however deliberately ignores the case of XTS
+ * since the latter isn't used in SSL/TLS. */
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+#define MBEDTLS_MAX_KEY_LENGTH 64
+#else
+#define MBEDTLS_MAX_KEY_LENGTH 32
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
/**
* Base cipher information (opaque struct).
*/
@@ -355,14 +356,32 @@ typedef struct mbedtls_cipher_context_t
/** CMAC-specific context. */
mbedtls_cmac_context_t *cmac_ctx;
#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /** Indicates whether the cipher operations should be performed
+ * by Mbed TLS' own crypto library or an external implementation
+ * of the PSA Crypto API.
+ * This is unset if the cipher context was established through
+ * mbedtls_cipher_setup(), and set if it was established through
+ * mbedtls_cipher_setup_psa().
+ */
+ unsigned char psa_enabled;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
} mbedtls_cipher_context_t;
/**
- * \brief This function retrieves the list of ciphers supported by the generic
- * cipher module.
+ * \brief This function retrieves the list of ciphers supported
+ * by the generic cipher module.
+ *
+ * For any cipher identifier in the returned list, you can
+ * obtain the corresponding generic cipher information structure
+ * via mbedtls_cipher_info_from_type(), which can then be used
+ * to prepare a cipher context via mbedtls_cipher_setup().
*
- * \return A statically-allocated array of ciphers. The last entry
- * is zero.
+ *
+ * \return A statically-allocated array of cipher identifiers
+ * of type cipher_type_t. The last entry is zero.
*/
const int *mbedtls_cipher_list( void );
@@ -429,9 +448,8 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
/**
- * \brief This function initializes and fills the cipher-context
- * structure with the appropriate values. It also clears
- * the structure.
+ * \brief This function initializes a cipher context for
+ * use with the given cipher primitive.
*
* \param ctx The context to initialize. This must be initialized.
* \param cipher_info The cipher to use.
@@ -449,6 +467,33 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx );
int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
const mbedtls_cipher_info_t *cipher_info );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief This function initializes a cipher context for
+ * PSA-based use with the given cipher primitive.
+ *
+ * \note See #MBEDTLS_USE_PSA_CRYPTO for information on PSA.
+ *
+ * \param ctx The context to initialize. May not be \c NULL.
+ * \param cipher_info The cipher to use.
+ * \param taglen For AEAD ciphers, the length in bytes of the
+ * authentication tag to use. Subsequent uses of
+ * mbedtls_cipher_auth_encrypt() or
+ * mbedtls_cipher_auth_decrypt() must provide
+ * the same tag length.
+ * For non-AEAD ciphers, the value must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_ALLOC_FAILED if allocation of the
+ * cipher-specific context fails.
+ */
+int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info,
+ size_t taglen );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/**
* \brief This function returns the block size of the given cipher.
*
@@ -671,7 +716,7 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx );
* \param ctx The generic cipher context. This must be initialized.
* \param ad The additional data to use. This must be a readable
* buffer of at least \p ad_len Bytes.
- * \param ad_len the Length of \p ad Bytes.
+ * \param ad_len The length of \p ad in Bytes.
*
* \return \c 0 on success.
* \return A specific error code on failure.
@@ -714,8 +759,10 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
* unsupported mode for a cipher.
* \return A cipher-specific error code on failure.
*/
-int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
- size_t ilen, unsigned char *output, size_t *olen );
+int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx,
+ const unsigned char *input,
+ size_t ilen, unsigned char *output,
+ size_t *olen );
/**
* \brief The generic cipher finalization function. If data still
@@ -818,30 +865,52 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
unsigned char *output, size_t *olen );
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_WARNING */
/**
- * \brief The generic autenticated encryption (AEAD) function.
+ * \brief The generic authenticated encryption (AEAD) function.
+ *
+ * \deprecated Superseded by mbedtls_cipher_auth_encrypt_ext().
+ *
+ * \note This function only supports AEAD algorithms, not key
+ * wrapping algorithms such as NIST_KW; for this, see
+ * mbedtls_cipher_auth_encrypt_ext().
*
* \param ctx The generic cipher context. This must be initialized and
- * bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
+ * bound to a key associated with an AEAD algorithm.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and must not be \c NULL.
+ * \param iv_len The length of the nonce. This must satisfy the
+ * constraints imposed by the AEAD cipher used.
* \param ad The additional data to authenticate. This must be a
- * readable buffer of at least \p ad_len Bytes.
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
* \param ilen The length of the input data.
- * \param output The buffer for the output data. This must be able to
- * hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p ilen Bytes, and must
+ * not be \c NULL.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
* \param tag The buffer for the authentication tag. This must be a
- * writable buffer of at least \p tag_len Bytes.
- * \param tag_len The desired length of the authentication tag.
+ * writable buffer of at least \p tag_len Bytes. See note
+ * below regarding restrictions with PSA-based contexts.
+ * \param tag_len The desired length of the authentication tag. This
+ * must match the constraints imposed by the AEAD cipher
+ * used, and in particular must not be \c 0.
+ *
+ * \note If the context is based on PSA (that is, it was set up
+ * with mbedtls_cipher_setup_psa()), then it is required
+ * that \c tag == output + ilen. That is, the tag must be
+ * appended to the ciphertext as recommended by RFC 5116.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -853,36 +922,53 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
- unsigned char *tag, size_t tag_len );
+ unsigned char *tag, size_t tag_len )
+ MBEDTLS_DEPRECATED;
/**
- * \brief The generic autenticated decryption (AEAD) function.
+ * \brief The generic authenticated decryption (AEAD) function.
+ *
+ * \deprecated Superseded by mbedtls_cipher_auth_decrypt_ext().
+ *
+ * \note This function only supports AEAD algorithms, not key
+ * wrapping algorithms such as NIST_KW; for this, see
+ * mbedtls_cipher_auth_decrypt_ext().
*
* \note If the data is not authentic, then the output buffer
* is zeroed out to prevent the unauthentic plaintext being
* used, making this interface safer.
*
* \param ctx The generic cipher context. This must be initialized and
- * and bound to a key.
- * \param iv The IV to use, or NONCE_COUNTER for CTR-mode ciphers.
- * This must be a readable buffer of at least \p iv_len
- * Bytes.
- * \param iv_len The IV length for ciphers with variable-size IV.
- * This parameter is discarded by ciphers with fixed-size IV.
- * \param ad The additional data to be authenticated. This must be a
- * readable buffer of at least \p ad_len Bytes.
+ * bound to a key associated with an AEAD algorithm.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and must not be \c NULL.
+ * \param iv_len The length of the nonce. This must satisfy the
+ * constraints imposed by the AEAD cipher used.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
* \param ad_len The length of \p ad.
* \param input The buffer holding the input data. This must be a
- * readable buffer of at least \p ilen Bytes.
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
* \param ilen The length of the input data.
- * \param output The buffer for the output data.
- * This must be able to hold at least \p ilen Bytes.
- * \param olen The length of the output data, to be updated with the
- * actual number of Bytes written. This must not be
- * \c NULL.
- * \param tag The buffer holding the authentication tag. This must be
- * a readable buffer of at least \p tag_len Bytes.
- * \param tag_len The length of the authentication tag.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p ilen Bytes, and must
+ * not be \c NULL.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag The buffer for the authentication tag. This must be a
+ * readable buffer of at least \p tag_len Bytes. See note
+ * below regarding restrictions with PSA-based contexts.
+ * \param tag_len The length of the authentication tag. This must match
+ * the constraints imposed by the AEAD cipher used, and in
+ * particular must not be \c 0.
+ *
+ * \note If the context is based on PSA (that is, it was set up
+ * with mbedtls_cipher_setup_psa()), then it is required
+ * that \c tag == input + len. That is, the tag must be
+ * appended to the ciphertext as recommended by RFC 5116.
*
* \return \c 0 on success.
* \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
@@ -895,9 +981,120 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
- const unsigned char *tag, size_t tag_len );
+ const unsigned char *tag, size_t tag_len )
+ MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+/**
+ * \brief The authenticated encryption (AEAD/NIST_KW) function.
+ *
+ * \note For AEAD modes, the tag will be appended to the
+ * ciphertext, as recommended by RFC 5116.
+ * (NIST_KW doesn't have a separate tag.)
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key, with an AEAD algorithm or NIST_KW.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and may be \c NULL if \p
+ * iv_len is \c 0.
+ * \param iv_len The length of the nonce. For AEAD ciphers, this must
+ * satisfy the constraints imposed by the cipher used.
+ * For NIST_KW, this must be \c 0.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
+ * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
+ * \param ilen The length of the input data.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p output_len Bytes, and
+ * must not be \c NULL.
+ * \param output_len The length of the \p output buffer in Bytes. For AEAD
+ * ciphers, this must be at least \p ilen + \p tag_len.
+ * For NIST_KW, this must be at least \p ilen + 8
+ * (rounded up to a multiple of 8 if KWP is used);
+ * \p ilen + 15 is always a safe value.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag_len The desired length of the authentication tag. For AEAD
+ * ciphers, this must match the constraints imposed by
+ * the cipher used, and in particular must not be \c 0.
+ * For NIST_KW, this must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len );
+
+/**
+ * \brief The authenticated encryption (AEAD/NIST_KW) function.
+ *
+ * \note If the data is not authentic, then the output buffer
+ * is zeroed out to prevent the unauthentic plaintext being
+ * used, making this interface safer.
+ *
+ * \note For AEAD modes, the tag must be appended to the
+ * ciphertext, as recommended by RFC 5116.
+ * (NIST_KW doesn't have a separate tag.)
+ *
+ * \param ctx The generic cipher context. This must be initialized and
+ * bound to a key, with an AEAD algorithm or NIST_KW.
+ * \param iv The nonce to use. This must be a readable buffer of
+ * at least \p iv_len Bytes and may be \c NULL if \p
+ * iv_len is \c 0.
+ * \param iv_len The length of the nonce. For AEAD ciphers, this must
+ * satisfy the constraints imposed by the cipher used.
+ * For NIST_KW, this must be \c 0.
+ * \param ad The additional data to authenticate. This must be a
+ * readable buffer of at least \p ad_len Bytes, and may
+ * be \c NULL is \p ad_len is \c 0.
+ * \param ad_len The length of \p ad. For NIST_KW, this must be \c 0.
+ * \param input The buffer holding the input data. This must be a
+ * readable buffer of at least \p ilen Bytes, and may be
+ * \c NULL if \p ilen is \c 0.
+ * \param ilen The length of the input data. For AEAD ciphers this
+ * must be at least \p tag_len. For NIST_KW this must be
+ * at least \c 8.
+ * \param output The buffer for the output data. This must be a
+ * writable buffer of at least \p output_len Bytes, and
+ * may be \c NULL if \p output_len is \c 0.
+ * \param output_len The length of the \p output buffer in Bytes. For AEAD
+ * ciphers, this must be at least \p ilen - \p tag_len.
+ * For NIST_KW, this must be at least \p ilen - 8.
+ * \param olen This will be filled with the actual number of Bytes
+ * written to the \p output buffer. This must point to a
+ * writable object of type \c size_t.
+ * \param tag_len The actual length of the authentication tag. For AEAD
+ * ciphers, this must match the constraints imposed by
+ * the cipher used, and in particular must not be \c 0.
+ * For NIST_KW, this must be \c 0.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA on
+ * parameter-verification failure.
+ * \return #MBEDTLS_ERR_CIPHER_AUTH_FAILED if data is not authentic.
+ * \return A cipher-specific error code on failure.
+ */
+int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
index 88282ec9d2..2484c01c7a 100644
--- a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,38 +20,21 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CIPHER_WRAP_H
#define MBEDTLS_CIPHER_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "cipher.h"
+#include "mbedtls/cipher.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#ifdef __cplusplus
extern "C" {
@@ -139,6 +116,29 @@ typedef struct
const mbedtls_cipher_info_t *info;
} mbedtls_cipher_definition_t;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+typedef enum
+{
+ MBEDTLS_CIPHER_PSA_KEY_UNSET = 0,
+ MBEDTLS_CIPHER_PSA_KEY_OWNED, /* Used for PSA-based cipher contexts which */
+ /* use raw key material internally imported */
+ /* as a volatile key, and which hence need */
+ /* to destroy that key when the context is */
+ /* freed. */
+ MBEDTLS_CIPHER_PSA_KEY_NOT_OWNED, /* Used for PSA-based cipher contexts */
+ /* which use a key provided by the */
+ /* user, and which hence will not be */
+ /* destroyed when the context is freed. */
+} mbedtls_cipher_psa_key_ownership;
+
+typedef struct
+{
+ psa_algorithm_t alg;
+ psa_key_id_t slot;
+ mbedtls_cipher_psa_key_ownership slot_state;
+} mbedtls_cipher_context_psa;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
extern const mbedtls_cipher_definition_t mbedtls_cipher_definitions[];
extern int mbedtls_cipher_supported[];
diff --git a/thirdparty/mbedtls/include/mbedtls/cmac.h b/thirdparty/mbedtls/include/mbedtls/cmac.h
index a73909cf86..8934886af7 100644
--- a/thirdparty/mbedtls/include/mbedtls/cmac.h
+++ b/thirdparty/mbedtls/include/mbedtls/cmac.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -27,39 +21,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CMAC_H
#define MBEDTLS_CMAC_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "cipher.h"
+#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {
@@ -113,6 +86,12 @@ struct mbedtls_cmac_context_t
* To start a CMAC computation using the same key as a previous
* CMAC computation, use mbedtls_cipher_cmac_finish().
*
+ * \note When the CMAC implementation is supplied by an alternate
+ * implementation (through #MBEDTLS_CMAC_ALT), some ciphers
+ * may not be supported by that implementation, and thus
+ * return an error. Alternate implementations must support
+ * AES-128 and AES-256, and may support AES-192 and 3DES.
+ *
* \param ctx The cipher context used for the CMAC operation, initialized
* as one of the following types: MBEDTLS_CIPHER_AES_128_ECB,
* MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_CIPHER_AES_256_ECB,
@@ -199,6 +178,11 @@ int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx );
* The CMAC result is calculated as
* output = generic CMAC(cmac key, input buffer).
*
+ * \note When the CMAC implementation is supplied by an alternate
+ * implementation (through #MBEDTLS_CMAC_ALT), some ciphers
+ * may not be supported by that implementation, and thus
+ * return an error. Alternate implementations must support
+ * AES-128 and AES-256, and may support AES-192 and 3DES.
*
* \param cipher_info The cipher information.
* \param key The CMAC key.
@@ -243,6 +227,13 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len,
/**
* \brief The CMAC checkup routine.
*
+ * \note In case the CMAC routines are provided by an alternative
+ * implementation (i.e. #MBEDTLS_CMAC_ALT is defined), the
+ * checkup routine will succeed even if the implementation does
+ * not support the less widely used AES-192 or 3DES primitives.
+ * The self-test requires at least AES-128 and AES-256 to be
+ * supported by the underlying implementation.
+ *
* \return \c 0 on success.
* \return \c 1 on failure.
*/
diff --git a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
index 45e5a1cf77..40177512ca 100644
--- a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
+++ b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -27,31 +21,10 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -1275,9 +1248,9 @@
#define POLARSSL_KEY_EXCHANGE_PSK MBEDTLS_KEY_EXCHANGE_PSK
#define POLARSSL_KEY_EXCHANGE_RSA MBEDTLS_KEY_EXCHANGE_RSA
#define POLARSSL_KEY_EXCHANGE_RSA_PSK MBEDTLS_KEY_EXCHANGE_RSA_PSK
-#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
-#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
-#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED
+#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
+#define POLARSSL_KEY_EXCHANGE__WITH_CERT__ENABLED MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED
#define POLARSSL_KEY_LENGTH_DES MBEDTLS_KEY_LENGTH_DES
#define POLARSSL_KEY_LENGTH_DES_EDE MBEDTLS_KEY_LENGTH_DES_EDE
#define POLARSSL_KEY_LENGTH_DES_EDE3 MBEDTLS_KEY_LENGTH_DES_EDE3
diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h
index d53b457630..87b4e9192e 100644
--- a/thirdparty/mbedtls/include/mbedtls/config.h
+++ b/thirdparty/mbedtls/include/mbedtls/config.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,27 +22,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CONFIG_H
@@ -251,33 +224,34 @@
//#define MBEDTLS_PLATFORM_FPRINTF_ALT
//#define MBEDTLS_PLATFORM_PRINTF_ALT
//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT
//#define MBEDTLS_PLATFORM_NV_SEED_ALT
//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
/**
* \def MBEDTLS_DEPRECATED_WARNING
*
- * Mark deprecated functions so that they generate a warning if used.
- * Functions deprecated in one version will usually be removed in the next
- * version. You can enable this to help you prepare the transition to a new
- * major version by making sure your code is not using these functions.
+ * Mark deprecated functions and features so that they generate a warning if
+ * used. Functionality deprecated in one version will usually be removed in the
+ * next version. You can enable this to help you prepare the transition to a
+ * new major version by making sure your code is not using this functionality.
*
* This only works with GCC and Clang. With other compilers, you may want to
* use MBEDTLS_DEPRECATED_REMOVED
*
- * Uncomment to get warnings on using deprecated functions.
+ * Uncomment to get warnings on using deprecated functions and features.
*/
//#define MBEDTLS_DEPRECATED_WARNING
/**
* \def MBEDTLS_DEPRECATED_REMOVED
*
- * Remove deprecated functions so that they generate an error if used.
- * Functions deprecated in one version will usually be removed in the next
- * version. You can enable this to help you prepare the transition to a new
- * major version by making sure your code is not using these functions.
+ * Remove deprecated functions and features so that they generate an error if
+ * used. Functionality deprecated in one version will usually be removed in the
+ * next version. You can enable this to help you prepare the transition to a
+ * new major version by making sure your code is not using this functionality.
*
- * Uncomment to get errors on using deprecated functions.
+ * Uncomment to get errors on using deprecated functions and features.
*/
//#define MBEDTLS_DEPRECATED_REMOVED
@@ -319,7 +293,7 @@
* the function mbedtls_param_failed() in your application.
* See `platform_util.h` for its prototype.
* - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the
- * library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
+ * library defines MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`.
* You can still supply an alternative definition of
* MBEDTLS_PARAM_FAILED(), which may call `assert`.
* - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h`
@@ -510,6 +484,11 @@
* is still present and it is used for group structures not supported by the
* alternative.
*
+ * The original implementation can in addition be removed by setting the
+ * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the
+ * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be
+ * able to fallback to curves not supported by the alternative implementation.
+ *
* Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
* and implementing the following functions:
* unsigned char mbedtls_internal_ecp_grp_capable(
@@ -523,21 +502,28 @@
* called before and after each point operation and provide an opportunity to
* implement optimized set up and tear down instructions.
*
- * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
- * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
- * function, but will use your mbedtls_internal_ecp_double_jac if the group is
- * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
- * receives it as an argument). If the group is not supported then the original
- * implementation is used. The other functions and the definition of
- * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
- * implementation of mbedtls_internal_ecp_double_jac and
- * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac()
+ * function, but will use your mbedtls_internal_ecp_double_jac() if the group
+ * for the operation is supported by your implementation (i.e. your
+ * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the
+ * group is not supported by your implementation, then the original mbed TLS
+ * implementation of ecp_double_jac() is used instead, unless this fallback
+ * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case
+ * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE).
+ *
+ * The function prototypes and the definition of mbedtls_ecp_group and
+ * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your
+ * implementation of mbedtls_internal_ecp__function_name__ must be compatible
+ * with their definitions.
*
* Uncomment a macro to enable alternate implementation of the corresponding
* function.
*/
/* Required for all the functions in this section */
//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Turn off software fallback for curves not supported in hardware */
+//#define MBEDTLS_ECP_NO_FALLBACK
/* Support for Weierstrass curves with Jacobi representation */
//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
//#define MBEDTLS_ECP_ADD_MIXED_ALT
@@ -550,42 +536,6 @@
//#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.
@@ -667,6 +617,29 @@
//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
/**
+ * \def MBEDTLS_CHECK_RETURN_WARNING
+ *
+ * If this macro is defined, emit a compile-time warning if application code
+ * calls a function without checking its return value, but the return value
+ * should generally be checked in portable applications.
+ *
+ * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is
+ * implemented. Otherwise this option has no effect.
+ *
+ * Uncomment to get warnings on using fallible functions without checking
+ * their return value.
+ *
+ * \note This feature is a work in progress.
+ * Warnings will be added to more functions in the future.
+ *
+ * \note A few functions are considered critical, and ignoring the return
+ * value of these functions will trigger a warning even if this
+ * macro is not defined. To completely disable return value check
+ * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion.
+ */
+//#define MBEDTLS_CHECK_RETURN_WARNING
+
+/**
* \def MBEDTLS_CIPHER_MODE_CBC
*
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
@@ -816,6 +789,7 @@
*
* Comment macros to disable the curve and functions for it
*/
+/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
@@ -827,6 +801,7 @@
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+/* Montgomery curves (supporting ECP) */
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_ECP_DP_CURVE448_ENABLED
@@ -849,11 +824,11 @@
* against some side-channel attacks.
*
* This protection introduces a dependency of the ECP module on one of the
- * DRBG or SHA modules (HMAC-DRBG, CTR-DRBG, SHA-512 or SHA-256.) For very
- * constrained applications that don't require this protection (for example,
- * because you're only doing signature verification, so not manipulating any
- * secret, or because local/physical side-channel attacks are outside your
- * threat model), it might be desirable to get rid of that dependency.
+ * DRBG modules. For very constrained implementations that don't require this
+ * protection (for example, because you're only doing signature verification,
+ * so not manipulating any secret, or because local/physical side-channel
+ * attacks are outside your threat model), it might be desirable to get rid of
+ * that dependency.
*
* \warning Enabling this option makes some uses of ECP vulnerable to some
* side-channel attacks. Only enable it if you know that's not a problem for
@@ -883,11 +858,40 @@
*
* \note This option only works with the default software implementation of
* elliptic curve functionality. It is incompatible with
- * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT
+ * and MBEDTLS_ECDH_LEGACY_CONTEXT.
*/
//#define MBEDTLS_ECP_RESTARTABLE
/**
+ * \def MBEDTLS_ECDH_LEGACY_CONTEXT
+ *
+ * Use a backward compatible ECDH context.
+ *
+ * Mbed TLS supports two formats for ECDH contexts (#mbedtls_ecdh_context
+ * defined in `ecdh.h`). For most applications, the choice of format makes
+ * no difference, since all library functions can work with either format,
+ * except that the new format is incompatible with MBEDTLS_ECP_RESTARTABLE.
+
+ * The new format used when this option is disabled is smaller
+ * (56 bytes on a 32-bit platform). In future versions of the library, it
+ * will support alternative implementations of ECDH operations.
+ * The new format is incompatible with applications that access
+ * context fields directly and with restartable ECP operations.
+ *
+ * Define this macro if you enable MBEDTLS_ECP_RESTARTABLE or if you
+ * want to access ECDH context fields directly. Otherwise you should
+ * comment out this macro definition.
+ *
+ * This option has no effect if #MBEDTLS_ECDH_C is not enabled.
+ *
+ * \note This configuration option is experimental. Future versions of the
+ * library may modify the way the ECDH context layout is configured
+ * and may modify the layout of the new context type.
+ */
+#define MBEDTLS_ECDH_LEGACY_CONTEXT
+
+/**
* \def MBEDTLS_ECDSA_DETERMINISTIC
*
* Enable deterministic ECDSA (RFC 6979).
@@ -895,7 +899,7 @@
* may result in a compromise of the long-term signing key. This is avoided by
* the deterministic variant.
*
- * Requires: MBEDTLS_HMAC_DRBG_C
+ * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C
*
* Comment this macro to disable deterministic ECDSA.
*/
@@ -1114,7 +1118,7 @@
*
* Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
*
- * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@@ -1138,7 +1142,7 @@
*
* Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
*
- * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
@@ -1289,6 +1293,18 @@
*/
//#define MBEDTLS_ENTROPY_NV_SEED
+/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+ *
+ * Enable key identifiers that encode a key owner identifier.
+ *
+ * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t
+ * which is currently hard-coded to be int32_t.
+ *
+ * Note that this option is meant for internal use only and may be removed
+ * without notice. It is incompatible with MBEDTLS_USE_PSA_CRYPTO.
+ */
+//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+
/**
* \def MBEDTLS_MEMORY_DEBUG
*
@@ -1345,6 +1361,114 @@
*/
#define MBEDTLS_PKCS1_V21
+/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
+ *
+ * Enable support for platform built-in keys. If you enable this feature,
+ * you must implement the function mbedtls_psa_platform_get_builtin_key().
+ * See the documentation of that function for more information.
+ *
+ * Built-in keys are typically derived from a hardware unique key or
+ * stored in a secure element.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C.
+ *
+ * \warning This interface is experimental and may change or be removed
+ * without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS
+
+/** \def MBEDTLS_PSA_CRYPTO_CLIENT
+ *
+ * Enable support for PSA crypto client.
+ *
+ * \note This option allows to include the code necessary for a PSA
+ * crypto client when the PSA crypto implementation is not included in
+ * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the
+ * code to set and get PSA key attributes.
+ * The development of PSA drivers partially relying on the library to
+ * fulfill the hardware gaps is another possible usage of this option.
+ *
+ * \warning This interface is experimental and may change or be removed
+ * without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CLIENT
+
+/** \def MBEDTLS_PSA_CRYPTO_DRIVERS
+ *
+ * Enable support for the experimental PSA crypto driver interface.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ * \warning This interface is experimental and may change or be removed
+ * without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_DRIVERS
+
+/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+ *
+ * Make the PSA Crypto module use an external random generator provided
+ * by a driver, instead of Mbed TLS's entropy and DRBG modules.
+ *
+ * \note This random generator must deliver random numbers with cryptographic
+ * quality and high performance. It must supply unpredictable numbers
+ * with a uniform distribution. The implementation of this function
+ * is responsible for ensuring that the random generator is seeded
+ * with sufficient entropy. If you have a hardware TRNG which is slow
+ * or delivers non-uniform output, declare it as an entropy source
+ * with mbedtls_entropy_add_source() instead of enabling this option.
+ *
+ * If you enable this option, you must configure the type
+ * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h
+ * and define a function called mbedtls_psa_external_get_random()
+ * with the following prototype:
+ * ```
+ * psa_status_t mbedtls_psa_external_get_random(
+ * mbedtls_psa_external_random_context_t *context,
+ * uint8_t *output, size_t output_size, size_t *output_length);
+ * );
+ * ```
+ * The \c context value is initialized to 0 before the first call.
+ * The function must fill the \c output buffer with \p output_size bytes
+ * of random data and set \c *output_length to \p output_size.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ * \warning If you enable this option, code that uses the PSA cryptography
+ * interface will not use any of the entropy sources set up for
+ * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED
+ * enables.
+ *
+ * \note This option is experimental and may be removed without notice.
+ */
+//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_SPM
+ *
+ * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
+ * Partition Manager) integration which separates the code into two parts: a
+ * NSPE (Non-Secure Process Environment) and an SPE (Secure Process
+ * Environment).
+ *
+ * Module: library/psa_crypto.c
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_SPM
+
+/**
+ * \def MBEDTLS_PSA_INJECT_ENTROPY
+ *
+ * Enable support for entropy injection at first boot. This feature is
+ * required on systems that do not have a built-in entropy source (TRNG).
+ * This feature is currently not supported on systems that have a built-in
+ * entropy source.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED
+ *
+ */
+//#define MBEDTLS_PSA_INJECT_ENTROPY
+
/**
* \def MBEDTLS_RSA_NO_CRT
*
@@ -1380,6 +1504,28 @@
//#define MBEDTLS_SHA256_SMALLER
/**
+ * \def MBEDTLS_SHA512_SMALLER
+ *
+ * Enable an implementation of SHA-512 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * Uncomment to enable the smaller implementation of SHA512.
+ */
+//#define MBEDTLS_SHA512_SMALLER
+
+/**
+ * \def MBEDTLS_SHA512_NO_SHA384
+ *
+ * Disable the SHA-384 option of the SHA-512 module. Use this to save some
+ * code size on devices that don't use SHA-384.
+ *
+ * Requires: MBEDTLS_SHA512_C
+ *
+ * Uncomment to disable SHA-384
+ */
+//#define MBEDTLS_SHA512_NO_SHA384
+
+/**
* \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
*
* Enable sending of alert messages in case of encountered errors as per RFC.
@@ -1394,6 +1540,48 @@
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
/**
+ * \def MBEDTLS_SSL_RECORD_CHECKING
+ *
+ * Enable the function mbedtls_ssl_check_record() which can be used to check
+ * the validity and authenticity of an incoming record, to verify that it has
+ * not been seen before. These checks are performed without modifying the
+ * externally visible state of the SSL context.
+ *
+ * See mbedtls_ssl_check_record() for more information.
+ *
+ * Uncomment to enable support for record checking.
+ */
+#define MBEDTLS_SSL_RECORD_CHECKING
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CONNECTION_ID
+ *
+ * Enable support for the DTLS Connection ID extension
+ * (version draft-ietf-tls-dtls-connection-id-05,
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05)
+ * which allows to identify DTLS connections across changes
+ * in the underlying transport.
+ *
+ * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`,
+ * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`.
+ * See the corresponding documentation for more information.
+ *
+ * \warning The Connection ID extension is still in draft state.
+ * We make no stability promises for the availability
+ * or the shape of the API controlled by this option.
+ *
+ * The maximum lengths of outgoing and incoming CIDs can be configured
+ * through the options
+ * - MBEDTLS_SSL_CID_OUT_LEN_MAX
+ * - MBEDTLS_SSL_CID_IN_LEN_MAX.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Uncomment to enable the Connection ID extension.
+ */
+//#define MBEDTLS_SSL_DTLS_CONNECTION_ID
+
+/**
* \def MBEDTLS_SSL_ASYNC_PRIVATE
*
* Enable asynchronous external private key operations in SSL. This allows
@@ -1405,6 +1593,33 @@
//#define MBEDTLS_SSL_ASYNC_PRIVATE
/**
+ * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION
+ *
+ * Enable serialization of the TLS context structures, through use of the
+ * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load().
+ *
+ * This pair of functions allows one side of a connection to serialize the
+ * context associated with the connection, then free or re-use that context
+ * while the serialized state is persisted elsewhere, and finally deserialize
+ * that state to a live context for resuming read/write operations on the
+ * connection. From a protocol perspective, the state of the connection is
+ * unaffected, in particular this is entirely transparent to the peer.
+ *
+ * Note: this is distinct from TLS session resumption, which is part of the
+ * protocol and fully visible by the peer. TLS session resumption enables
+ * establishing new connections associated to a saved session with shorter,
+ * lighter handshakes, while context serialization is a local optimization in
+ * handling a single, potentially long-lived connection.
+ *
+ * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are
+ * saved after the handshake to allow for more efficient serialization, so if
+ * you don't need this feature you'll save RAM by disabling it.
+ *
+ * Comment to disable the context serialization APIs.
+ */
+#define MBEDTLS_SSL_CONTEXT_SERIALIZATION
+
+/**
* \def MBEDTLS_SSL_DEBUG_ALL
*
* Enable the debug messages in SSL module for all issues.
@@ -1440,8 +1655,8 @@
/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
*
- * Enable support for Extended Master Secret, aka Session Hash
- * (draft-ietf-tls-session-hash-02).
+ * Enable support for RFC 7627: Session Hash and Extended Master Secret
+ * Extension.
*
* This was introduced as "the proper fix" to the Triple Handshake familiy of
* attacks, but it is recommended to always use it (even if you disable
@@ -1459,7 +1674,8 @@
/**
* \def MBEDTLS_SSL_FALLBACK_SCSV
*
- * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ * Enable support for RFC 7507: Fallback Signaling Cipher Suite Value (SCSV)
+ * for Preventing Protocol Downgrade Attacks.
*
* For servers, it is recommended to always enable this, unless you support
* only one version of TLS, or know for sure that none of your clients
@@ -1474,11 +1690,36 @@
#define MBEDTLS_SSL_FALLBACK_SCSV
/**
+ * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+ *
+ * This option controls the availability of the API mbedtls_ssl_get_peer_cert()
+ * giving access to the peer's certificate after completion of the handshake.
+ *
+ * Unless you need mbedtls_ssl_peer_cert() in your application, it is
+ * recommended to disable this option for reduced RAM usage.
+ *
+ * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still
+ * defined, but always returns \c NULL.
+ *
+ * \note This option has no influence on the protection against the
+ * triple handshake attack. Even if it is disabled, Mbed TLS will
+ * still ensure that certificates do not change during renegotiation,
+ * for exaple by keeping a hash of the peer's certificate.
+ *
+ * Comment this macro to disable storing the peer's certificate
+ * after the handshake.
+ */
+#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+
+/**
* \def MBEDTLS_SSL_HW_RECORD_ACCEL
*
* Enable hooking functions in SSL module for hardware acceleration of
* individual records.
*
+ * \deprecated This option is deprecated and will be removed in a future
+ * version of Mbed TLS.
+ *
* Uncomment this macro to enable hooking functions.
*/
//#define MBEDTLS_SSL_HW_RECORD_ACCEL
@@ -1523,6 +1764,9 @@
* Enable support for receiving and parsing SSLv2 Client Hello messages for the
* SSL Server module (MBEDTLS_SSL_SRV_C).
*
+ * \deprecated This option is deprecated and will be removed in a future
+ * version of Mbed TLS.
+ *
* Uncomment this macro to enable support for SSLv2 Client Hello messages.
*/
//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
@@ -1554,6 +1798,9 @@
* Requires: MBEDTLS_MD5_C
* MBEDTLS_SHA1_C
*
+ * \deprecated This option is deprecated and will be removed in a future
+ * version of Mbed TLS.
+ *
* Comment this macro to disable support for SSL 3.0
*/
//#define MBEDTLS_SSL_PROTO_SSL3
@@ -1595,6 +1842,25 @@
#define MBEDTLS_SSL_PROTO_TLS1_2
/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+ *
+ * This macro is used to selectively enable experimental parts
+ * of the code that contribute to the ongoing development of
+ * the prototype TLS 1.3 and DTLS 1.3 implementation, and provide
+ * no other purpose.
+ *
+ * \warning TLS 1.3 and DTLS 1.3 aren't yet supported in Mbed TLS,
+ * and no feature exposed through this macro is part of the
+ * public API. In particular, features under the control
+ * of this macro are experimental and don't come with any
+ * stability guarantees.
+ *
+ * Uncomment this macro to enable experimental and partial
+ * functionality specific to TLS 1.3.
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL
+
+/**
* \def MBEDTLS_SSL_PROTO_DTLS
*
* Enable support for DTLS (all available versions).
@@ -1652,6 +1918,37 @@
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
/**
+ * \def MBEDTLS_SSL_DTLS_SRTP
+ *
+ * Enable support for negotiation of DTLS-SRTP (RFC 5764)
+ * through the use_srtp extension.
+ *
+ * \note This feature provides the minimum functionality required
+ * to negotiate the use of DTLS-SRTP and to allow the derivation of
+ * the associated SRTP packet protection key material.
+ * In particular, the SRTP packet protection itself, as well as the
+ * demultiplexing of RTP and DTLS packets at the datagram layer
+ * (see Section 5 of RFC 5764), are not handled by this feature.
+ * Instead, after successful completion of a handshake negotiating
+ * the use of DTLS-SRTP, the extended key exporter API
+ * mbedtls_ssl_conf_export_keys_ext_cb() should be used to implement
+ * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705
+ * (this is implemented in the SSL example programs).
+ * The resulting key should then be passed to an SRTP stack.
+ *
+ * Setting this option enables the runtime API
+ * mbedtls_ssl_conf_dtls_srtp_protection_profiles()
+ * through which the supported DTLS-SRTP protection
+ * profiles can be configured. You must call this API at
+ * runtime if you wish to negotiate the use of DTLS-SRTP.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Uncomment this to enable support for use_srtp extension.
+ */
+//#define MBEDTLS_SSL_DTLS_SRTP
+
+/**
* \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
*
* Enable server-side support for clients that reconnect from the same port.
@@ -1727,8 +2024,8 @@
*
* Fallback to old (pre-2.7), non-conforming implementation of the truncated
* HMAC extension which also truncates the HMAC key. Note that this option is
- * only meant for a transitory upgrade period and is likely to be removed in
- * a future version of the library.
+ * only meant for a transitory upgrade period and will be removed in a future
+ * version of the library.
*
* \warning The old implementation is non-compliant and has a security weakness
* (2^80 brute force attack on the HMAC key used for a single,
@@ -1737,7 +2034,7 @@
* bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
* the fixed implementation yet (pre-2.7).
*
- * \deprecated This option is deprecated and will likely be removed in a
+ * \deprecated This option is deprecated and will be removed in a
* future version of Mbed TLS.
*
* Uncomment to fallback to old, non-compliant truncated HMAC implementation.
@@ -1747,6 +2044,52 @@
//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
/**
+ * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ *
+ * When this option is enabled, the SSL buffer will be resized automatically
+ * based on the negotiated maximum fragment length in each direction.
+ *
+ * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ */
+//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+
+/**
+ * \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_HOOKS
*
* Enable features for invasive testing such as introspection functions and
@@ -1759,6 +2102,9 @@
* risk of vulnerabilities, and more gadgets that can make exploits easier.
* Therefore this feature must never be enabled in production.
*
+ * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more
+ * information.
+ *
* Uncomment to enable invasive tests.
*/
//#define MBEDTLS_TEST_HOOKS
@@ -1786,6 +2132,49 @@
//#define MBEDTLS_THREADING_PTHREAD
/**
+ * \def MBEDTLS_USE_PSA_CRYPTO
+ *
+ * Make the X.509 and TLS library use PSA for cryptographic operations, and
+ * enable new APIs for using keys handled by PSA Crypto.
+ *
+ * \note Development of this option is currently in progress, and parts of Mbed
+ * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts
+ * will still continue to work as usual, so enabling this option should not
+ * break backwards compatibility.
+ *
+ * \note See docs/use-psa-crypto.md for a complete description of what this
+ * option currently does, and of parts that are not affected by it so far.
+ *
+ * \warning This option enables new Mbed TLS APIs which are currently
+ * considered experimental and may change in incompatible ways at any time.
+ * That is, the APIs enabled by this option are not covered by the usual
+ * promises of API stability.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C.
+ *
+ * Uncomment this to enable internal use of PSA Crypto and new associated APIs.
+ */
+//#define MBEDTLS_USE_PSA_CRYPTO
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_CONFIG
+ *
+ * This setting allows support for cryptographic mechanisms through the PSA
+ * API to be configured separately from support through the mbedtls API.
+ *
+ * Uncomment this to enable use of PSA Crypto configuration settings which
+ * can be found in include/psa/crypto_config.h.
+ *
+ * If you enable this option and write your own configuration file, you must
+ * include mbedtls/config_psa.h in your configuration file. The default
+ * provided mbedtls/config.h contains the necessary inclusion.
+ *
+ * This feature is still experimental and is not ready for production since
+ * it is not completed.
+ */
+//#define MBEDTLS_PSA_CRYPTO_CONFIG
+
+/**
* \def MBEDTLS_VERSION_FEATURES
*
* Allow run-time checking of compile-time enabled features. Thus allowing users
@@ -1821,6 +2210,25 @@
//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
/**
+ * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+ *
+ * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()`
+ * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure
+ * the set of trusted certificates through a callback instead of a linked
+ * list.
+ *
+ * This is useful for example in environments where a large number of trusted
+ * certificates is present and storing them in a linked list isn't efficient
+ * enough, or when the set of trusted certificates changes frequently.
+ *
+ * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and
+ * `mbedtls_ssl_conf_ca_cb()` for more information.
+ *
+ * Uncomment to enable trusted certificate callbacks.
+ */
+//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
+
+/**
* \def MBEDTLS_X509_CHECK_KEY_USAGE
*
* Enable verification of the keyUsage extension (CA and leaf certificates).
@@ -2244,6 +2652,11 @@
* Enable the CMAC (Cipher-based Message Authentication Code) mode for block
* ciphers.
*
+ * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying
+ * implementation of the CMAC algorithm is provided by an alternate
+ * implementation, that alternate implementation may opt to not support
+ * AES-192 or 3DES as underlying block ciphers for the CMAC operation.
+ *
* Module: library/cmac.c
*
* Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
@@ -2362,7 +2775,9 @@
* This module is used by the following key exchanges:
* ECDHE-ECDSA
*
- * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C,
+ * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a
+ * short Weierstrass curve.
*/
#define MBEDTLS_ECDSA_C
@@ -2428,11 +2843,11 @@
/**
* \def MBEDTLS_GCM_C
*
- * Enable the Galois/Counter Mode (GCM) for AES.
+ * Enable the Galois/Counter Mode (GCM).
*
* Module: library/gcm.c
*
- * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or MBEDTLS_ARIA_C
*
* This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
* requisites are enabled as well.
@@ -2642,9 +3057,7 @@
*
* This modules adds support for the VIA PadLock on x86.
*/
-// -- GODOT start --
-// #define MBEDTLS_PADLOCK_C
-// -- GODOT end --
+#define MBEDTLS_PADLOCK_C
/**
* \def MBEDTLS_PEM_PARSE_C
@@ -2741,7 +3154,10 @@
/**
* \def MBEDTLS_PKCS11_C
*
- * Enable wrapper for PKCS#11 smartcard support.
+ * Enable wrapper for PKCS#11 smartcard support via the pkcs11-helper library.
+ *
+ * \deprecated This option is deprecated and will be removed in a future
+ * version of Mbed TLS.
*
* Module: library/pkcs11.c
* Caller: library/pk.c
@@ -2800,6 +3216,61 @@
#define MBEDTLS_POLY1305_C
/**
+ * \def MBEDTLS_PSA_CRYPTO_C
+ *
+ * Enable the Platform Security Architecture cryptography API.
+ *
+ * Module: library/psa_crypto.c
+ *
+ * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
+ * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
+ * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
+ *
+ */
+#define MBEDTLS_PSA_CRYPTO_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_SE_C
+ *
+ * Enable secure element support in the Platform Security Architecture
+ * cryptography API.
+ *
+ * \warning This feature is not yet suitable for production. It is provided
+ * for API evaluation and testing purposes only.
+ *
+ * Module: library/psa_crypto_se.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_SE_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_STORAGE_C
+ *
+ * Enable the Platform Security Architecture persistent key storage.
+ *
+ * Module: library/psa_crypto_storage.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C,
+ * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of
+ * the PSA ITS interface
+ */
+#define MBEDTLS_PSA_CRYPTO_STORAGE_C
+
+/**
+ * \def MBEDTLS_PSA_ITS_FILE_C
+ *
+ * Enable the emulation of the Platform Security Architecture
+ * Internal Trusted Storage (PSA ITS) over files.
+ *
+ * Module: library/psa_its_file.c
+ *
+ * Requires: MBEDTLS_FS_IO
+ */
+#define MBEDTLS_PSA_ITS_FILE_C
+
+/**
* \def MBEDTLS_RIPEMD160_C
*
* Enable the RIPEMD-160 hash algorithm.
@@ -3162,8 +3633,8 @@
//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
/* ECP options */
-//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
-//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups. Normally determined automatically from the configured curves. */
+//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */
//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
/* Entropy options */
@@ -3201,6 +3672,7 @@
//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */
/* Note: your snprintf must correctly zero-terminate the buffer! */
//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */
//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
@@ -3240,6 +3712,53 @@
*/
//#define MBEDTLS_PARAM_FAILED( cond ) assert( cond )
+/** \def MBEDTLS_CHECK_RETURN
+ *
+ * This macro is used at the beginning of the declaration of a function
+ * to indicate that its return value should be checked. It should
+ * instruct the compiler to emit a warning or an error if the function
+ * is called without checking its return value.
+ *
+ * There is a default implementation for popular compilers in platform_util.h.
+ * You can override the default implementation by defining your own here.
+ *
+ * If the implementation here is empty, this will effectively disable the
+ * checking of functions' return values.
+ */
+//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * This macro requires one argument, which should be a C function call.
+ * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this
+ * warning is suppressed.
+ */
+//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result))
+
+/* PSA options */
+/**
+ * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the
+ * PSA crypto subsystem.
+ *
+ * If this option is unset:
+ * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG.
+ * - Otherwise, the PSA subsystem uses HMAC_DRBG with either
+ * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and
+ * on unspecified heuristics.
+ */
+//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+
+/** \def MBEDTLS_PSA_KEY_SLOT_COUNT
+ * Restrict the PSA library to supporting a maximum amount of simultaneously
+ * loaded keys. A loaded key is a key stored by the PSA Crypto core as a
+ * volatile key, or a persistent key which is loaded temporarily by the
+ * library as part of a crypto operation in flight.
+ *
+ * If this option is unset, the library will fall back to a default value of
+ * 32 keys.
+ */
+//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
+
/* SSL Cache options */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
@@ -3297,6 +3816,53 @@
*/
//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384
+/** \def MBEDTLS_SSL_CID_IN_LEN_MAX
+ *
+ * The maximum length of CIDs used for incoming DTLS messages.
+ *
+ */
+//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32
+
+/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX
+ *
+ * The maximum length of CIDs used for outgoing DTLS messages.
+ *
+ */
+//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32
+
+/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY
+ *
+ * This option controls the use of record plaintext padding
+ * when using the Connection ID extension in DTLS 1.2.
+ *
+ * The padding will always be chosen so that the length of the
+ * padded plaintext is a multiple of the value of this option.
+ *
+ * Note: A value of \c 1 means that no padding will be used
+ * for outgoing records.
+ *
+ * Note: On systems lacking division instructions,
+ * a power of two should be preferred.
+ *
+ */
+//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16
+
+/** \def MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY
+ *
+ * This option controls the use of record plaintext padding
+ * in TLS 1.3.
+ *
+ * The padding will always be chosen so that the length of the
+ * padded plaintext is a multiple of the value of this option.
+ *
+ * Note: A value of \c 1 means that no padding will be used
+ * for outgoing records.
+ *
+ * Note: On systems lacking division instructions,
+ * a power of two should be preferred.
+ */
+//#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1
+
/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
*
* Maximum length (in bytes) of outgoing plaintext fragments.
@@ -3326,7 +3892,7 @@
* Maximum number of heap-allocated bytes for the purpose of
* DTLS handshake message reassembly and future message buffering.
*
- * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN
* to account for a reassembled handshake message of maximum size,
* together with its reassembly bitmap.
*
@@ -3342,6 +3908,17 @@
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+/** \def MBEDTLS_TLS_EXT_CID
+ *
+ * At the time of writing, the CID extension has not been assigned its
+ * final value. Set this configuration option to make Mbed TLS use a
+ * different value.
+ *
+ * A future minor revision of Mbed TLS may change the default value of
+ * this option to match evolving standards and usage.
+ */
+//#define MBEDTLS_TLS_EXT_CID 254
+
/**
* Complete list of ciphersuites to use, in order of preference.
*
@@ -3361,20 +3938,6 @@
//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
/**
- * Allow SHA-1 in the default TLS configuration for certificate signing.
- * Without this build-time option, SHA-1 support must be activated explicitly
- * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
- * recommended because of it is possible to generate SHA-1 collisions, however
- * this may be safe for legacy infrastructure where additional controls apply.
- *
- * \warning SHA-1 is considered a weak message digest and its use constitutes
- * a security risk. If possible, we recommend avoiding dependencies
- * on it, and considering stronger message digests instead.
- *
- */
-// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
-
-/**
* Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
* signature and ciphersuite selection. Without this build-time option, SHA-1
* support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
@@ -3389,7 +3952,7 @@
* on it, and considering stronger message digests instead.
*
*/
-#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
/**
* Uncomment the macro to let mbed TLS use your alternate implementation of
@@ -3430,6 +3993,15 @@
*/
//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+/**
+ * Enable the verified implementations of ECDH primitives from Project Everest
+ * (currently only Curve25519). This feature changes the layout of ECDH
+ * contexts and therefore is a compatibility break for applications that access
+ * fields of a mbedtls_ecdh_context structure directly. See also
+ * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h.
+ */
+//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED
+
/* \} name SECTION: Customisation configuration options */
/* Target and application specific configurations
@@ -3441,6 +4013,10 @@
#include MBEDTLS_USER_CONFIG_FILE
#endif
-#include "check_config.h"
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+#include "mbedtls/config_psa.h"
+#endif
+
+#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */
diff --git a/thirdparty/mbedtls/include/mbedtls/constant_time.h b/thirdparty/mbedtls/include/mbedtls/constant_time.h
new file mode 100644
index 0000000000..c5de57a01f
--- /dev/null
+++ b/thirdparty/mbedtls/include/mbedtls/constant_time.h
@@ -0,0 +1,45 @@
+/**
+ * Constant-time functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_H
+#define MBEDTLS_CONSTANT_TIME_H
+
+#include <stddef.h>
+
+
+/** Constant-time buffer comparison without branches.
+ *
+ * This is equivalent to the standard memcmp function, but is likely to be
+ * compiled to code using bitwise operation rather than a branch.
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param a Pointer to the first buffer.
+ * \param b Pointer to the second buffer.
+ * \param n The number of bytes to compare in the buffer.
+ *
+ * \return Zero if the content of the two buffer is the same,
+ * otherwise non-zero.
+ */
+int mbedtls_ct_memcmp( const void *a,
+ const void *b,
+ size_t n );
+
+#endif /* MBEDTLS_CONSTANT_TIME_H */
diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
index 892e3e3531..dc4adc896d 100644
--- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h
@@ -12,40 +12,18 @@
* The Mbed TLS implementation of CTR_DRBG uses AES-256 (default) or AES-128
* (if \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is enabled at compile time)
* as the underlying block cipher, with a derivation function.
- * The initial seeding grabs #MBEDTLS_CTR_DRBG_ENTROPY_LEN bytes of entropy.
- * See the documentation of mbedtls_ctr_drbg_seed() for more details.
- *
- * Based on NIST SP 800-90A §10.2.1 table 3 and NIST SP 800-57 part 1 table 2,
- * here are the security strengths achieved in typical configuration:
- * - 256 bits under the default configuration of the library, with AES-256
- * and with #MBEDTLS_CTR_DRBG_ENTROPY_LEN set to 48 or more.
- * - 256 bits if AES-256 is used, #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set
- * to 32 or more, and the DRBG is initialized with an explicit
- * nonce in the \c custom parameter to mbedtls_ctr_drbg_seed().
- * - 128 bits if AES-256 is used but #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
- * between 24 and 47 and the DRBG is not initialized with an explicit
- * nonce (see mbedtls_ctr_drbg_seed()).
- * - 128 bits if AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
- * and #MBEDTLS_CTR_DRBG_ENTROPY_LEN is set to 24 or more (which is
- * always the case unless it is explicitly set to a different value
- * in config.h).
- *
- * Note that the value of #MBEDTLS_CTR_DRBG_ENTROPY_LEN defaults to:
- * - \c 48 if the module \c MBEDTLS_SHA512_C is enabled and the symbol
- * \c MBEDTLS_ENTROPY_FORCE_SHA256 is disabled at compile time.
- * This is the default configuration of the library.
- * - \c 32 if the module \c MBEDTLS_SHA512_C is disabled at compile time.
- * - \c 32 if \c MBEDTLS_ENTROPY_FORCE_SHA256 is enabled at compile time.
+ *
+ * The security strength as defined in NIST SP 800-90A is
+ * 128 bits when AES-128 is used (\c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY enabled)
+ * and 256 bits otherwise, provided that #MBEDTLS_CTR_DRBG_ENTROPY_LEN is
+ * kept at its default value (and not overridden in config.h) and that the
+ * DRBG instance is set up with default parameters.
+ * See the documentation of mbedtls_ctr_drbg_seed() for more
+ * information.
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -58,42 +36,21 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_CTR_DRBG_H
#define MBEDTLS_CTR_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "aes.h"
+#include "mbedtls/aes.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
/** The entropy source failed. */
@@ -192,20 +149,49 @@
extern "C" {
#endif
+#if MBEDTLS_CTR_DRBG_ENTROPY_LEN >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
+/** The default length of the nonce read from the entropy source.
+ *
+ * This is \c 0 because a single read from the entropy source is sufficient
+ * to include a nonce.
+ * See the documentation of mbedtls_ctr_drbg_seed() for more information.
+ */
+#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN 0
+#else
+/** The default length of the nonce read from the entropy source.
+ *
+ * This is half of the default entropy length because a single read from
+ * the entropy source does not provide enough material to form a nonce.
+ * See the documentation of mbedtls_ctr_drbg_seed() for more information.
+ */
+#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN ( MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1 ) / 2
+#endif
+
/**
* \brief The CTR_DRBG context structure.
*/
typedef struct mbedtls_ctr_drbg_context
{
unsigned char counter[16]; /*!< The counter (V). */
- int reseed_counter; /*!< The reseed counter. */
+ int reseed_counter; /*!< The reseed counter.
+ * This is the number of requests that have
+ * been made since the last (re)seeding,
+ * minus one.
+ * Before the initial seeding, this field
+ * contains the amount of entropy in bytes
+ * to use as a nonce for the initial seeding,
+ * or -1 if no nonce length has been explicitly
+ * set (see mbedtls_ctr_drbg_set_nonce_len()).
+ */
int prediction_resistance; /*!< This determines whether prediction
resistance is enabled, that is
whether to systematically reseed before
each random generation. */
size_t entropy_len; /*!< The amount of entropy grabbed on each
- seed or reseed operation. */
- int reseed_interval; /*!< The reseed interval. */
+ seed or reseed operation, in bytes. */
+ int reseed_interval; /*!< The reseed interval.
+ * This is the maximum number of requests
+ * that can be made between reseedings. */
mbedtls_aes_context aes_ctx; /*!< The AES context. */
@@ -258,34 +244,35 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* The entropy length is #MBEDTLS_CTR_DRBG_ENTROPY_LEN by default.
* You can override it by calling mbedtls_ctr_drbg_set_entropy_len().
*
- * You can provide a personalization string in addition to the
+ * The entropy nonce length is:
+ * - \c 0 if the entropy length is at least 3/2 times the entropy length,
+ * which guarantees that the security strength is the maximum permitted
+ * by the key size and entropy length according to NIST SP 800-90A §10.2.1;
+ * - Half the entropy length otherwise.
+ * You can override it by calling mbedtls_ctr_drbg_set_nonce_len().
+ * With the default entropy length, the entropy nonce length is
+ * #MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN.
+ *
+ * You can provide a nonce and personalization string in addition to the
* entropy source, to make this instantiation as unique as possible.
+ * See SP 800-90A §8.6.7 for more details about nonces.
*
- * \note The _seed_material_ value passed to the derivation
- * function in the CTR_DRBG Instantiate Process
- * described in NIST SP 800-90A §10.2.1.3.2
- * is the concatenation of the string obtained from
- * calling \p f_entropy and the \p custom string.
- * The origin of the nonce depends on the value of
- * the entropy length relative to the security strength.
- * - If the entropy length is at least 1.5 times the
- * security strength then the nonce is taken from the
- * string obtained with \p f_entropy.
- * - If the entropy length is less than the security
- * strength, then the nonce is taken from \p custom.
- * In this case, for compliance with SP 800-90A,
- * you must pass a unique value of \p custom at
- * each invocation. See SP 800-90A §8.6.7 for more
- * details.
- */
-#if MBEDTLS_CTR_DRBG_ENTROPY_LEN < MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2
-/** \warning When #MBEDTLS_CTR_DRBG_ENTROPY_LEN is less than
- * #MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2, to achieve the
- * maximum security strength permitted by CTR_DRBG,
- * you must pass a value of \p custom that is a nonce:
- * this value must never be repeated in subsequent
- * runs of the same application or on a different
- * device.
+ * The _seed_material_ value passed to the derivation function in
+ * the CTR_DRBG Instantiate Process described in NIST SP 800-90A §10.2.1.3.2
+ * is the concatenation of the following strings:
+ * - A string obtained by calling \p f_entropy function for the entropy
+ * length.
+ */
+#if MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN == 0
+/**
+ * - If mbedtls_ctr_drbg_set_nonce_len() has been called, a string
+ * obtained by calling \p f_entropy function for the specified length.
+ */
+#else
+/**
+ * - A string obtained by calling \p f_entropy function for the entropy nonce
+ * length. If the entropy nonce length is \c 0, this function does not
+ * make a second call to \p f_entropy.
*/
#endif
#if defined(MBEDTLS_THREADING_C)
@@ -298,6 +285,23 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
*/
#endif /* MBEDTLS_THREADING_C */
/**
+ * - The \p custom string.
+ *
+ * \note To achieve the nominal security strength permitted
+ * by CTR_DRBG, the entropy length must be:
+ * - at least 16 bytes for a 128-bit strength
+ * (maximum achievable strength when using AES-128);
+ * - at least 32 bytes for a 256-bit strength
+ * (maximum achievable strength when using AES-256).
+ *
+ * In addition, if you do not pass a nonce in \p custom,
+ * the sum of the entropy length
+ * and the entropy nonce length must be:
+ * - at least 24 bytes for a 128-bit strength
+ * (maximum achievable strength when using AES-128);
+ * - at least 48 bytes for a 256-bit strength
+ * (maximum achievable strength when using AES-256).
+ *
* \param ctx The CTR_DRBG context to seed.
* It must have been initialized with
* mbedtls_ctr_drbg_init().
@@ -312,7 +316,7 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx );
* \p p_entropy context, the buffer to fill, and the
* length of the buffer.
* \p f_entropy is always called with a buffer size
- * equal to the entropy length.
+ * less than or equal to the entropy length.
* \param p_entropy The entropy context to pass to \p f_entropy.
* \param custom The personalization string.
* This can be \c NULL, in which case the personalization
@@ -375,12 +379,36 @@ void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
*
* \param ctx The CTR_DRBG context.
* \param len The amount of entropy to grab, in bytes.
- * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
+ * and at most the maximum length accepted by the
+ * entropy function that is set in the context.
*/
void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
size_t len );
/**
+ * \brief This function sets the amount of entropy grabbed
+ * as a nonce for the initial seeding.
+ *
+ * Call this function before calling mbedtls_ctr_drbg_seed() to read
+ * a nonce from the entropy source during the initial seeding.
+ *
+ * \param ctx The CTR_DRBG context.
+ * \param len The amount of entropy to grab for the nonce, in bytes.
+ * This must be at most #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT
+ * and at most the maximum length accepted by the
+ * entropy function that is set in the context.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG if \p len is
+ * more than #MBEDTLS_CTR_DRBG_MAX_SEED_INPUT.
+ * \return #MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED
+ * if the initial seeding has already taken place.
+ */
+int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len );
+
+/**
* \brief This function sets the reseed interval.
*
* The reseed interval is the number of calls to mbedtls_ctr_drbg_random()
@@ -421,10 +449,10 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
/**
* \brief This function updates the state of the CTR_DRBG context.
*
- * \note This function is not thread-safe. It is not safe
- * to call this function if another thread might be
- * concurrently obtaining random numbers from the same
- * context or updating or reseeding the same context.
+ * \note This function is not thread-safe. It is not safe
+ * to call this function if another thread might be
+ * concurrently obtaining random numbers from the same
+ * context or updating or reseeding the same context.
*
* \param ctx The CTR_DRBG context.
* \param additional The data to update the state with. This must not be
@@ -576,11 +604,6 @@ int mbedtls_ctr_drbg_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
-/* Internal functions (do not call directly) */
-int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *,
- int (*)(void *, unsigned char *, size_t), void *,
- const unsigned char *, size_t, size_t );
-
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/debug.h b/thirdparty/mbedtls/include/mbedtls/debug.h
index abc2d4f07c..3c08244f3d 100644
--- a/thirdparty/mbedtls/include/mbedtls/debug.h
+++ b/thirdparty/mbedtls/include/mbedtls/debug.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,41 +18,20 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_DEBUG_H
#define MBEDTLS_DEBUG_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ssl.h"
+#include "mbedtls/ssl.h"
#if defined(MBEDTLS_ECP_C)
-#include "ecp.h"
+#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_DEBUG_C)
@@ -107,6 +80,55 @@
#endif /* MBEDTLS_DEBUG_C */
+/**
+ * \def MBEDTLS_PRINTF_ATTRIBUTE
+ *
+ * Mark a function as having printf attributes, and thus enable checking
+ * via -wFormat and other flags. This does nothing on builds with compilers
+ * that do not support the format attribute
+ *
+ * Module: library/debug.c
+ * Caller:
+ *
+ * This module provides debugging functions.
+ */
+#if defined(__has_attribute)
+#if __has_attribute(format)
+#if defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1
+#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \
+ __attribute__((__format__ (gnu_printf, string_index, first_to_check)))
+#else /* defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 1 */
+#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check) \
+ __attribute__((format(printf, string_index, first_to_check)))
+#endif
+#else /* __has_attribute(format) */
+#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check)
+#endif /* __has_attribute(format) */
+#else /* defined(__has_attribute) */
+#define MBEDTLS_PRINTF_ATTRIBUTE(string_index, first_to_check)
+#endif
+
+/**
+ * \def MBEDTLS_PRINTF_SIZET
+ *
+ * MBEDTLS_PRINTF_xxx: Due to issues with older window compilers
+ * and MinGW we need to define the printf specifier for size_t
+ * and long long per platform.
+ *
+ * Module: library/debug.c
+ * Caller:
+ *
+ * This module provides debugging functions.
+ */
+#if (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800)
+ #include <inttypes.h>
+ #define MBEDTLS_PRINTF_SIZET PRIuPTR
+ #define MBEDTLS_PRINTF_LONGLONG "I64d"
+#else /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
+ #define MBEDTLS_PRINTF_SIZET "zu"
+ #define MBEDTLS_PRINTF_LONGLONG "lld"
+#endif /* (defined(__MINGW32__) && __USE_MINGW_ANSI_STDIO == 0) || (defined(_MSC_VER) && _MSC_VER < 1800) */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -145,7 +167,7 @@ void mbedtls_debug_set_threshold( int threshold );
*/
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
- const char *format, ... );
+ const char *format, ... ) MBEDTLS_PRINTF_ATTRIBUTE(5, 6);
/**
* \brief Print the return value of a function to the debug output. This
@@ -287,4 +309,3 @@ void mbedtls_debug_printf_ecdh( const mbedtls_ssl_context *ssl, int level,
#endif
#endif /* debug.h */
-
diff --git a/thirdparty/mbedtls/include/mbedtls/des.h b/thirdparty/mbedtls/include/mbedtls/des.h
index f689acb39a..325aab5364 100644
--- a/thirdparty/mbedtls/include/mbedtls/des.h
+++ b/thirdparty/mbedtls/include/mbedtls/des.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -29,36 +23,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
#ifndef MBEDTLS_DES_H
#define MBEDTLS_DES_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
+#include "mbedtls/platform_util.h"
#include <stddef.h>
#include <stdint.h>
@@ -173,6 +147,7 @@ void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] );
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
@@ -186,6 +161,7 @@ int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SI
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
@@ -200,6 +176,7 @@ int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
@@ -214,6 +191,7 @@ int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MB
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] );
/**
@@ -224,6 +202,7 @@ int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MB
*
* \return 0
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
@@ -235,6 +214,7 @@ int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx,
*
* \return 0
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] );
@@ -246,6 +226,7 @@ int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx,
*
* \return 0
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
@@ -257,6 +238,7 @@ int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx,
*
* \return 0
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] );
@@ -273,6 +255,7 @@ int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx,
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
@@ -300,6 +283,7 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
* security risk. We recommend considering stronger ciphers
* instead.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
int mode,
size_t length,
@@ -317,6 +301,7 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
*
* \return 0 if successful
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
const unsigned char input[8],
unsigned char output[8] );
@@ -342,6 +327,7 @@ int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
*
* \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
int mode,
size_t length,
@@ -372,6 +358,7 @@ void mbedtls_des_setkey( uint32_t SK[32],
*
* \return 0 if successful, or 1 if the test failed
*/
+MBEDTLS_CHECK_RETURN_CRITICAL
int mbedtls_des_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */
diff --git a/thirdparty/mbedtls/include/mbedtls/dhm.h b/thirdparty/mbedtls/include/mbedtls/dhm.h
index 3ddbf3f735..c4b15a2c45 100644
--- a/thirdparty/mbedtls/include/mbedtls/dhm.h
+++ b/thirdparty/mbedtls/include/mbedtls/dhm.h
@@ -45,13 +45,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -64,38 +58,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_DHM_H
#define MBEDTLS_DHM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
+#include "mbedtls/bignum.h"
/*
* DHM Error codes
@@ -334,7 +307,6 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
void mbedtls_dhm_free( mbedtls_dhm_context *ctx );
#if defined(MBEDTLS_ASN1_PARSE_C)
-/** \ingroup x509_module */
/**
* \brief This function parses DHM parameters in PEM or DER format.
*
@@ -353,7 +325,6 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen );
#if defined(MBEDTLS_FS_IO)
-/** \ingroup x509_module */
/**
* \brief This function loads and parses DHM parameters from a file.
*
diff --git a/thirdparty/mbedtls/include/mbedtls/ecdh.h b/thirdparty/mbedtls/include/mbedtls/ecdh.h
index b9324bc496..05855cdf10 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecdh.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecdh.h
@@ -14,13 +14,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -33,51 +27,23 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ECDH_H
#define MBEDTLS_ECDH_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ecp.h"
+#include "mbedtls/ecp.h"
-/*
- * Use a backward compatible ECDH context.
- *
- * This flag is always enabled for now and future versions might add a
- * configuration option that conditionally undefines this flag.
- * The configuration option in question may have a different name.
- *
- * Features undefining this flag, must have a warning in their description in
- * config.h stating that the feature breaks backward compatibility.
- */
-#define MBEDTLS_ECDH_LEGACY_CONTEXT
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+#undef MBEDTLS_ECDH_LEGACY_CONTEXT
+#include "everest/everest.h"
+#endif
#ifdef __cplusplus
extern "C" {
@@ -103,6 +69,9 @@ typedef enum
{
MBEDTLS_ECDH_VARIANT_NONE = 0, /*!< Implementation not defined. */
MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0,/*!< The default Mbed TLS implementation */
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ MBEDTLS_ECDH_VARIANT_EVEREST /*!< Everest implementation */
+#endif
} mbedtls_ecdh_variant;
/**
@@ -156,6 +125,9 @@ typedef struct mbedtls_ecdh_context
union
{
mbedtls_ecdh_context_mbed mbed_ecdh;
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ mbedtls_ecdh_context_everest everest_ecdh;
+#endif
} ctx; /*!< Implementation-specific context. The
context in use is specified by the \c var
field. */
@@ -171,6 +143,15 @@ typedef struct mbedtls_ecdh_context
mbedtls_ecdh_context;
/**
+ * \brief Check whether a given group can be used for ECDH.
+ *
+ * \param gid The ECP group ID to check.
+ *
+ * \return \c 1 if the group can be used, \c 0 otherwise
+ */
+int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid );
+
+/**
* \brief This function generates an ECDH keypair on an elliptic
* curve.
*
diff --git a/thirdparty/mbedtls/include/mbedtls/ecdsa.h b/thirdparty/mbedtls/include/mbedtls/ecdsa.h
index da02b27864..264a638bb5 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecdsa.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecdsa.h
@@ -12,13 +12,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -31,60 +25,44 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ECDSA_H
#define MBEDTLS_ECDSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ecp.h"
-#include "md.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
-/*
- * RFC-4492 page 20:
+/**
+ * \brief Maximum ECDSA signature size for a given curve bit size
*
+ * \param bits Curve size in bits
+ * \return Maximum signature size in bytes
+ *
+ * \note This macro returns a compile-time constant if its argument
+ * is one. It may evaluate its argument multiple times.
+ */
+/*
* Ecdsa-Sig-Value ::= SEQUENCE {
* r INTEGER,
* s INTEGER
* }
*
- * Size is at most
- * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s,
- * twice that + 1 (tag) + 2 (len) for the sequence
- * (assuming ECP_MAX_BYTES is less than 126 for r and s,
- * and less than 124 (total len <= 255) for the sequence)
+ * For each of r and s, the value (V) may include an extra initial "0" bit.
*/
-#if MBEDTLS_ECP_MAX_BYTES > 124
-#error "MBEDTLS_ECP_MAX_BYTES bigger than expected, please fix MBEDTLS_ECDSA_MAX_LEN"
-#endif
+#define MBEDTLS_ECDSA_MAX_SIG_LEN( bits ) \
+ ( /*T,L of SEQUENCE*/ ( ( bits ) >= 61 * 8 ? 3 : 2 ) + \
+ /*T,L of r,s*/ 2 * ( ( ( bits ) >= 127 * 8 ? 3 : 2 ) + \
+ /*V of r,s*/ ( ( bits ) + 8 ) / 8 ) )
+
/** The maximal size of an ECDSA signature in Bytes. */
-#define MBEDTLS_ECDSA_MAX_LEN ( 3 + 2 * ( 3 + MBEDTLS_ECP_MAX_BYTES ) )
+#define MBEDTLS_ECDSA_MAX_LEN MBEDTLS_ECDSA_MAX_SIG_LEN( MBEDTLS_ECP_MAX_BITS )
#ifdef __cplusplus
extern "C" {
@@ -146,6 +124,16 @@ typedef void mbedtls_ecdsa_restart_ctx;
#endif /* MBEDTLS_ECP_RESTARTABLE */
/**
+ * \brief This function checks whether a given group can be used
+ * for ECDSA.
+ *
+ * \param gid The ECP group ID to check.
+ *
+ * \return \c 1 if the group can be used, \c 0 otherwise
+ */
+int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid );
+
+/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message.
*
@@ -186,6 +174,12 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
+#if ! defined(MBEDTLS_DEPRECATED_REMOVED)
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
@@ -237,7 +231,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg );
+ mbedtls_md_type_t md_alg ) MBEDTLS_DEPRECATED;
+#undef MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
/**
* \brief This function computes the ECDSA signature of a
* previously-hashed message, deterministic version.
@@ -278,12 +275,11 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
* error code on failure.
*/
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
- mbedtls_mpi *s, const mbedtls_mpi *d,
- const unsigned char *buf, size_t blen,
- mbedtls_md_type_t md_alg,
- int (*f_rng_blind)(void *, unsigned char *,
- size_t),
- void *p_rng_blind );
+ mbedtls_mpi *s, const mbedtls_mpi *d,
+ const unsigned char *buf, size_t blen,
+ mbedtls_md_type_t md_alg,
+ int (*f_rng_blind)(void *, unsigned char *, size_t),
+ void *p_rng_blind );
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
/**
@@ -362,7 +358,8 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
* the signature written. Must not be \c NULL.
* \param f_rng The RNG function. This must not be \c NULL if
* #MBEDTLS_ECDSA_DETERMINISTIC is unset. Otherwise,
- * it is unused and may be set to \c NULL.
+ * it is used only for blinding and may be set to \c NULL, but
+ * doing so is DEPRECATED.
* \param p_rng The RNG context to be passed to \p f_rng. This may be
* \c NULL if \p f_rng is \c NULL or doesn't use a context.
*
diff --git a/thirdparty/mbedtls/include/mbedtls/ecjpake.h b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
index a9b68d00c6..891705d8c4 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecjpake.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecjpake.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,27 +18,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
@@ -66,13 +39,13 @@
* also be use outside TLS.
*/
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ecp.h"
-#include "md.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/ecp.h b/thirdparty/mbedtls/include/mbedtls/ecp.h
index 18178c115e..0924341e00 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecp.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecp.h
@@ -16,13 +16,7 @@
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -35,39 +29,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ECP_H
#define MBEDTLS_ECP_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
+#include "mbedtls/bignum.h"
/*
* ECP error codes
@@ -96,6 +69,26 @@
/** Operation in progress, call again with the same parameters to continue. */
#define MBEDTLS_ERR_ECP_IN_PROGRESS -0x4B00
+/* Flags indicating whether to include code that is specific to certain
+ * types of curves. These flags are for internal library use only. */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+#define MBEDTLS_ECP_MONTGOMERY_ENABLED
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -109,6 +102,21 @@ extern "C" {
* parameters. Therefore, only standardized domain parameters from trusted
* sources should be used. See mbedtls_ecp_group_load().
*/
+/* Note: when adding a new curve:
+ * - Add it at the end of this enum, otherwise you'll break the ABI by
+ * changing the numerical value for existing curves.
+ * - Increment MBEDTLS_ECP_DP_MAX below if needed.
+ * - Update the calculation of MBEDTLS_ECP_MAX_BITS_MIN below.
+ * - Add the corresponding MBEDTLS_ECP_DP_xxx_ENABLED macro definition to
+ * config.h.
+ * - List the curve as a dependency of MBEDTLS_ECP_C and
+ * MBEDTLS_ECDSA_C if supported in check_config.h.
+ * - Add the curve to the appropriate curve type macro
+ * MBEDTLS_ECP_yyy_ENABLED above.
+ * - Add the necessary definitions to ecp_curves.c.
+ * - Add the curve to the ecp_supported_curves array in ecp.c.
+ * - Add the curve to applicable profiles in x509_crt.c if applicable.
+ */
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0, /*!< Curve not defined. */
@@ -134,6 +142,16 @@ typedef enum
*/
#define MBEDTLS_ECP_DP_MAX 12
+/*
+ * Curve types
+ */
+typedef enum
+{
+ MBEDTLS_ECP_TYPE_NONE = 0,
+ MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
+ MBEDTLS_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
+} mbedtls_ecp_curve_type;
+
/**
* Curve information, for use by other modules.
*/
@@ -278,11 +296,17 @@ mbedtls_ecp_group;
#error "MBEDTLS_ECP_MAX_BITS is smaller than the largest supported curve"
#endif
-#else
+#elif defined(MBEDTLS_ECP_C)
/**
* The maximum size of the groups, that is, of \c N and \c P.
*/
-#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */
+#define MBEDTLS_ECP_MAX_BITS MBEDTLS_ECP_MAX_BITS_MIN
+
+#else
+/* MBEDTLS_ECP_MAX_BITS is not relevant without MBEDTLS_ECP_C, but set it
+ * to a nonzero value so that code that unconditionally allocates an array
+ * of a size based on it keeps working if built without ECC support. */
+#define MBEDTLS_ECP_MAX_BITS 1
#endif
#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 )
@@ -291,7 +315,8 @@ mbedtls_ecp_group;
#if !defined(MBEDTLS_ECP_WINDOW_SIZE)
/*
* Maximum "window" size used for point multiplication.
- * Default: 6.
+ * Default: a point where higher memory usage yields disminishing performance
+ * returns.
* Minimum value: 2. Maximum value: 7.
*
* Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) )
@@ -308,7 +333,7 @@ mbedtls_ecp_group;
* 224 475 475 453 398 342
* 192 640 640 633 587 476
*/
-#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */
+#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< The maximum window size used. */
#endif /* MBEDTLS_ECP_WINDOW_SIZE */
#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM)
@@ -492,10 +517,20 @@ void mbedtls_ecp_set_max_ops( unsigned max_ops );
int mbedtls_ecp_restart_is_enabled( void );
#endif /* MBEDTLS_ECP_RESTARTABLE */
+/*
+ * Get the type of a curve
+ */
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp );
+
/**
* \brief This function retrieves the information defined in
- * mbedtls_ecp_curve_info() for all supported curves in order
- * of preference.
+ * mbedtls_ecp_curve_info() for all supported curves.
+ *
+ * \note This function returns information about all curves
+ * supported by the library. Some curves may not be
+ * supported for all algorithms. Call mbedtls_ecdh_can_do()
+ * or mbedtls_ecdsa_can_do() to check if a curve is
+ * supported for ECDH or ECDSA.
*
* \return A statically allocated array. The last entry is 0.
*/
@@ -506,6 +541,12 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void );
* identifiers of all supported curves in the order of
* preference.
*
+ * \note This function returns information about all curves
+ * supported by the library. Some curves may not be
+ * supported for all algorithms. Call mbedtls_ecdh_can_do()
+ * or mbedtls_ecdsa_can_do() to check if a curve is
+ * supported for ECDH or ECDSA.
+ *
* \return A statically allocated array,
* terminated with MBEDTLS_ECP_DP_NONE.
*/
@@ -701,6 +742,9 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
* \param P The point to export. This must be initialized.
* \param format The point format. This must be either
* #MBEDTLS_ECP_PF_COMPRESSED or #MBEDTLS_ECP_PF_UNCOMPRESSED.
+ * (For groups without these formats, this parameter is
+ * ignored. But it still has to be either of the above
+ * values.)
* \param olen The address at which to store the length of
* the output in Bytes. This must not be \c NULL.
* \param buf The output buffer. This must be a writable buffer
@@ -710,11 +754,14 @@ int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the output buffer
* is too small to hold the point.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
+ * or the export for the given group is not implemented.
* \return Another negative error code on other kinds of failure.
*/
-int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P,
- int format, size_t *olen,
- unsigned char *buf, size_t buflen );
+int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
+ const mbedtls_ecp_point *P,
+ int format, size_t *olen,
+ unsigned char *buf, size_t buflen );
/**
* \brief This function imports a point from unsigned binary data.
@@ -735,8 +782,8 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_
* \return \c 0 on success.
* \return #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the input is invalid.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
- * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
- * is not implemented.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the import for the
+ * given group is not implemented.
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P,
@@ -948,6 +995,7 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx );
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
@@ -957,6 +1005,10 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* \note In contrast to mbedtls_ecp_mul(), this function does not
* guarantee a constant execution flow and timing.
*
+ * \note This function is only defined for short Weierstrass curves.
+ * It may not be included in builds without any short
+ * Weierstrass curve.
+ *
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
@@ -975,6 +1027,8 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
+ * designate a short Weierstrass curve.
* \return Another negative error code on other kinds of failure.
*/
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
@@ -992,6 +1046,10 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* but it can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
+ * \note This function is only defined for short Weierstrass curves.
+ * It may not be included in builds without any short
+ * Weierstrass curve.
+ *
* \param grp The ECP group to use.
* This must be initialized and have group parameters
* set, for example through mbedtls_ecp_group_load().
@@ -1011,6 +1069,8 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
* valid private keys, or \p P or \p Q are not valid public
* keys.
* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if \p grp does not
+ * designate a short Weierstrass curve.
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
* \return Another negative error code on other kinds of failure.
@@ -1020,6 +1080,7 @@ int mbedtls_ecp_muladd_restartable(
const mbedtls_mpi *m, const mbedtls_ecp_point *P,
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
/**
* \brief This function checks that a point is a valid public key
@@ -1172,6 +1233,46 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
void *p_rng );
/**
+ * \brief This function reads an elliptic curve private key.
+ *
+ * \param grp_id The ECP group identifier.
+ * \param key The destination key.
+ * \param buf The buffer containing the binary representation of the
+ * key. (Big endian integer for Weierstrass curves, byte
+ * string for Montgomery curves.)
+ * \param buflen The length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_INVALID_KEY error if the key is
+ * invalid.
+ * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
+ * the group is not implemented.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen );
+
+/**
+ * \brief This function exports an elliptic curve private key.
+ *
+ * \param key The private key.
+ * \param buf The output buffer for containing the binary representation
+ * of the key. (Big endian integer for Weierstrass curves, byte
+ * string for Montgomery curves.)
+ * \param buflen The total length of the buffer in bytes.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL if the \p key
+ representation is larger than the available space in \p buf.
+ * \return #MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the operation for
+ * the group is not implemented.
+ * \return Another negative error code on different kinds of failure.
+ */
+int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen );
+
+/**
* \brief This function checks that the keypair objects
* \p pub and \p prv have the same group and the
* same public point, and that the private key in
diff --git a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
index 0047bd4ef9..6a47a8ff27 100644
--- a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h
@@ -6,13 +6,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,27 +19,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -87,7 +60,7 @@
#define MBEDTLS_ECP_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -130,7 +103,7 @@ int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp );
*/
void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp );
-#if defined(ECP_SHORTWEIERSTRASS)
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
/**
@@ -270,9 +243,9 @@ int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt );
#endif
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp,
@@ -316,7 +289,7 @@ int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *P );
#endif
-#endif /* ECP_MONTGOMERY */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
diff --git a/thirdparty/mbedtls/include/mbedtls/entropy.h b/thirdparty/mbedtls/include/mbedtls/entropy.h
index eea786e352..deb3c50300 100644
--- a/thirdparty/mbedtls/include/mbedtls/entropy.h
+++ b/thirdparty/mbedtls/include/mbedtls/entropy.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ENTROPY_H
#define MBEDTLS_ENTROPY_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -58,21 +31,21 @@
#include <stddef.h>
#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
-#include "sha512.h"
+#include "mbedtls/sha512.h"
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#else
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
-#include "sha256.h"
+#include "mbedtls/sha256.h"
#endif
#endif
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_HAVEGE_C)
-#include "havege.h"
+#include "mbedtls/havege.h"
#endif
/** Critical entropy source failure. */
diff --git a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
index c348fe52d4..e1d7491aa2 100644
--- a/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
+++ b/thirdparty/mbedtls/include/mbedtls/entropy_poll.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ENTROPY_POLL_H
#define MBEDTLS_ENTROPY_POLL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h
index fa8582a391..50f2538508 100644
--- a/thirdparty/mbedtls/include/mbedtls/error.h
+++ b/thirdparty/mbedtls/include/mbedtls/error.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,39 +18,23 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_ERROR_H
#define MBEDTLS_ERROR_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
/**
* Error code layout.
*
@@ -77,9 +55,10 @@
* For historical reasons, low-level error codes are divided in even and odd,
* even codes were assigned first, and -1 is reserved for other errors.
*
- * Low-level module errors (0x0002-0x007E, 0x0003-0x007F)
+ * Low-level module errors (0x0002-0x007E, 0x0001-0x007F)
*
* Module Nr Codes assigned
+ * ERROR 2 0x006E 0x0001
* MPI 7 0x0002-0x0010
* GCM 3 0x0012-0x0014 0x0013-0x0013
* BLOWFISH 3 0x0016-0x0018 0x0017-0x0017
@@ -111,7 +90,7 @@
* CHACHA20 3 0x0051-0x0055
* POLY1305 3 0x0057-0x005B
* CHACHAPOLY 2 0x0054-0x0056
- * PLATFORM 1 0x0070-0x0072
+ * PLATFORM 2 0x0070-0x0072
*
* High-level module nr (3 bits - 0x0...-0x7...)
* Name ID Nr of Errors
@@ -125,9 +104,9 @@
* ECP 4 10 (Started from top)
* MD 5 5
* HKDF 5 1 (Started from top)
- * SSL 5 1 (Started from 0x5E80)
- * CIPHER 6 8
- * SSL 6 23 (Started from top)
+ * SSL 5 2 (Started from 0x5F00)
+ * CIPHER 6 8 (Started from 0x6080)
+ * SSL 6 24 (Started from top, plus 0x6000)
* SSL 7 32
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
@@ -137,6 +116,59 @@
extern "C" {
#endif
+/** Generic error */
+#define MBEDTLS_ERR_ERROR_GENERIC_ERROR -0x0001
+/** This is a bug in the library */
+#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED -0x006E
+
+/**
+ * \brief Combines a high-level and low-level error code together.
+ *
+ * Wrapper macro for mbedtls_error_add(). See that function for
+ * more details.
+ */
+#define MBEDTLS_ERROR_ADD( high, low ) \
+ mbedtls_error_add( high, low, __FILE__, __LINE__ )
+
+#if defined(MBEDTLS_TEST_HOOKS)
+/**
+ * \brief Testing hook called before adding/combining two error codes together.
+ * Only used when invasive testing is enabled via MBEDTLS_TEST_HOOKS.
+ */
+extern void (*mbedtls_test_hook_error_add)( int, int, const char *, int );
+#endif
+
+/**
+ * \brief Combines a high-level and low-level error code together.
+ *
+ * This function can be called directly however it is usually
+ * called via the #MBEDTLS_ERROR_ADD macro.
+ *
+ * While a value of zero is not a negative error code, it is still an
+ * error code (that denotes success) and can be combined with both a
+ * negative error code or another value of zero.
+ *
+ * \note When invasive testing is enabled via #MBEDTLS_TEST_HOOKS, also try to
+ * call \link mbedtls_test_hook_error_add \endlink.
+ *
+ * \param high high-level error code. See error.h for more details.
+ * \param low low-level error code. See error.h for more details.
+ * \param file file where this error code addition occurred.
+ * \param line line where this error code addition occurred.
+ */
+static inline int mbedtls_error_add( int high, int low,
+ const char *file, int line )
+{
+#if defined(MBEDTLS_TEST_HOOKS)
+ if( *mbedtls_test_hook_error_add != NULL )
+ ( *mbedtls_test_hook_error_add )( high, low, file, line );
+#endif
+ (void)file;
+ (void)line;
+
+ return( high + low );
+}
+
/**
* \brief Translate a mbed TLS error code into a string representation,
* Result is truncated if necessary and always includes a terminating
@@ -148,6 +180,36 @@ extern "C" {
*/
void mbedtls_strerror( int errnum, char *buffer, size_t buflen );
+/**
+ * \brief Translate the high-level part of an Mbed TLS error code into a string
+ * representation.
+ *
+ * This function returns a const pointer to an un-modifiable string. The caller
+ * must not try to modify the string. It is intended to be used mostly for
+ * logging purposes.
+ *
+ * \param error_code error code
+ *
+ * \return The string representation of the error code, or \c NULL if the error
+ * code is unknown.
+ */
+const char * mbedtls_high_level_strerr( int error_code );
+
+/**
+ * \brief Translate the low-level part of an Mbed TLS error code into a string
+ * representation.
+ *
+ * This function returns a const pointer to an un-modifiable string. The caller
+ * must not try to modify the string. It is intended to be used mostly for
+ * logging purposes.
+ *
+ * \param error_code error code
+ *
+ * \return The string representation of the error code, or \c NULL if the error
+ * code is unknown.
+ */
+const char * mbedtls_low_level_strerr( int error_code );
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h
index 031e11329f..9723a17b65 100644
--- a/thirdparty/mbedtls/include/mbedtls/gcm.h
+++ b/thirdparty/mbedtls/include/mbedtls/gcm.h
@@ -13,13 +13,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -32,39 +26,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_GCM_H
#define MBEDTLS_GCM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "cipher.h"
+#include "mbedtls/cipher.h"
#include <stdint.h>
diff --git a/thirdparty/mbedtls/include/mbedtls/havege.h b/thirdparty/mbedtls/include/mbedtls/havege.h
index e90839ddeb..7d27039e8c 100644
--- a/thirdparty/mbedtls/include/mbedtls/havege.h
+++ b/thirdparty/mbedtls/include/mbedtls/havege.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,38 +18,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_HAVEGE_H
#define MBEDTLS_HAVEGE_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
+#include <stdint.h>
#define MBEDTLS_HAVEGE_COLLECT_SIZE 1024
@@ -68,9 +42,9 @@ extern "C" {
*/
typedef struct mbedtls_havege_state
{
- int PT1, PT2, offset[2];
- int pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
- int WALK[8192];
+ uint32_t PT1, PT2, offset[2];
+ uint32_t pool[MBEDTLS_HAVEGE_COLLECT_SIZE];
+ uint32_t WALK[8192];
}
mbedtls_havege_state;
diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h
index 3cfc5aea33..223004b8ed 100644
--- a/thirdparty/mbedtls/include/mbedtls/hkdf.h
+++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -27,38 +21,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_HKDF_H
#define MBEDTLS_HKDF_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "md.h"
+#include "mbedtls/md.h"
/**
* \name HKDF Error codes
diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
index 9f48a80e72..79132d4d91 100644
--- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
+++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,41 +22,20 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_HMAC_DRBG_H
#define MBEDTLS_HMAC_DRBG_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "md.h"
+#include "mbedtls/md.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
/*
diff --git a/thirdparty/mbedtls/include/mbedtls/md.h b/thirdparty/mbedtls/include/mbedtls/md.h
index ebbe565ae3..84fafd2ac7 100644
--- a/thirdparty/mbedtls/include/mbedtls/md.h
+++ b/thirdparty/mbedtls/include/mbedtls/md.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,27 +20,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_MD_H
@@ -55,10 +28,11 @@
#include <stddef.h>
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
+#include "mbedtls/platform_util.h"
/** The selected feature is not available. */
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080
@@ -104,6 +78,12 @@ typedef enum {
#define MBEDTLS_MD_MAX_SIZE 32 /* longest known is SHA256 or less */
#endif
+#if defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_MD_MAX_BLOCK_SIZE 128
+#else
+#define MBEDTLS_MD_MAX_BLOCK_SIZE 64
+#endif
+
/**
* Opaque struct defined in md_internal.h.
*/
@@ -231,6 +211,7 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_
* failure.
* \return #MBEDTLS_ERR_MD_ALLOC_FAILED on memory-allocation failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac );
/**
@@ -252,6 +233,7 @@ int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_inf
* \return \c 0 on success.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_clone( mbedtls_md_context_t *dst,
const mbedtls_md_context_t *src );
@@ -301,6 +283,7 @@ const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_starts( mbedtls_md_context_t *ctx );
/**
@@ -319,6 +302,7 @@ int mbedtls_md_starts( mbedtls_md_context_t *ctx );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen );
/**
@@ -339,6 +323,7 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
/**
@@ -359,6 +344,7 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
unsigned char *output );
@@ -380,6 +366,7 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
* the file pointed by \p path.
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA if \p md_info was NULL.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
unsigned char *output );
#endif /* MBEDTLS_FS_IO */
@@ -402,6 +389,7 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path,
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
size_t keylen );
@@ -424,6 +412,7 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input,
size_t ilen );
@@ -445,6 +434,7 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
/**
@@ -462,6 +452,7 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output);
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
/**
@@ -486,11 +477,13 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx );
* \return #MBEDTLS_ERR_MD_BAD_INPUT_DATA on parameter-verification
* failure.
*/
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output );
/* Internal use */
+MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data );
#ifdef __cplusplus
diff --git a/thirdparty/mbedtls/include/mbedtls/md2.h b/thirdparty/mbedtls/include/mbedtls/md2.h
index 72982007ef..7f3d5cf446 100644
--- a/thirdparty/mbedtls/include/mbedtls/md2.h
+++ b/thirdparty/mbedtls/include/mbedtls/md2.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -29,33 +23,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
#ifndef MBEDTLS_MD2_H
#define MBEDTLS_MD2_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/md4.h b/thirdparty/mbedtls/include/mbedtls/md4.h
index 1ea9f6ce44..0238c6723a 100644
--- a/thirdparty/mbedtls/include/mbedtls/md4.h
+++ b/thirdparty/mbedtls/include/mbedtls/md4.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -29,33 +23,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
#ifndef MBEDTLS_MD4_H
#define MBEDTLS_MD4_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/md5.h b/thirdparty/mbedtls/include/mbedtls/md5.h
index fa60dd46c7..73e4dd2c2a 100644
--- a/thirdparty/mbedtls/include/mbedtls/md5.h
+++ b/thirdparty/mbedtls/include/mbedtls/md5.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,33 +22,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_MD5_H
#define MBEDTLS_MD5_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/md_internal.h b/thirdparty/mbedtls/include/mbedtls/md_internal.h
index 847f50aa0a..f33cdf6086 100644
--- a/thirdparty/mbedtls/include/mbedtls/md_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/md_internal.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,38 +22,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_MD_WRAP_H
#define MBEDTLS_MD_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "md.h"
+#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {
@@ -71,42 +44,17 @@ extern "C" {
*/
struct mbedtls_md_info_t
{
- /** Digest identifier */
- mbedtls_md_type_t type;
-
/** Name of the message digest */
const char * name;
+ /** Digest identifier */
+ mbedtls_md_type_t type;
+
/** Output length of the digest function in bytes */
- int size;
+ unsigned char size;
/** Block length of the digest function in bytes */
- int block_size;
-
- /** Digest initialisation function */
- int (*starts_func)( void *ctx );
-
- /** Digest update function */
- int (*update_func)( void *ctx, const unsigned char *input, size_t ilen );
-
- /** Digest finalisation function */
- int (*finish_func)( void *ctx, unsigned char *output );
-
- /** Generic digest function */
- int (*digest_func)( const unsigned char *input, size_t ilen,
- unsigned char *output );
-
- /** Allocate a new context */
- void * (*ctx_alloc_func)( void );
-
- /** Free the given context */
- void (*ctx_free_func)( void *ctx );
-
- /** Clone state from a context */
- void (*clone_func)( void *dst, const void *src );
-
- /** Internal use only */
- int (*process_func)( void *ctx, const unsigned char *input );
+ unsigned char block_size;
};
#if defined(MBEDTLS_MD2_C)
@@ -129,7 +77,9 @@ extern const mbedtls_md_info_t mbedtls_sha224_info;
extern const mbedtls_md_info_t mbedtls_sha256_info;
#endif
#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
extern const mbedtls_md_info_t mbedtls_sha384_info;
+#endif
extern const mbedtls_md_info_t mbedtls_sha512_info;
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
index 89c0617495..233977252a 100644
--- a/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
+++ b/thirdparty/mbedtls/include/mbedtls/memory_buffer_alloc.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_MEMORY_BUFFER_ALLOC_H
#define MBEDTLS_MEMORY_BUFFER_ALLOC_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/net.h b/thirdparty/mbedtls/include/mbedtls/net.h
index 6c7a49d3bd..66921887da 100644
--- a/thirdparty/mbedtls/include/mbedtls/net.h
+++ b/thirdparty/mbedtls/include/mbedtls/net.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,36 +20,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
-#include "net_sockets.h"
+#include "mbedtls/net_sockets.h"
#if defined(MBEDTLS_DEPRECATED_WARNING)
#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif /* MBEDTLS_DEPRECATED_WARNING */
diff --git a/thirdparty/mbedtls/include/mbedtls/net_sockets.h b/thirdparty/mbedtls/include/mbedtls/net_sockets.h
index 66eb4f4c04..ceb7d5f652 100644
--- a/thirdparty/mbedtls/include/mbedtls/net_sockets.h
+++ b/thirdparty/mbedtls/include/mbedtls/net_sockets.h
@@ -21,13 +21,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -40,38 +34,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_NET_SOCKETS_H
#define MBEDTLS_NET_SOCKETS_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ssl.h"
+#include "mbedtls/ssl.h"
#include <stddef.h>
#include <stdint.h>
@@ -308,6 +281,13 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
uint32_t timeout );
/**
+ * \brief Closes down the connection and free associated data
+ *
+ * \param ctx The context to close
+ */
+void mbedtls_net_close( mbedtls_net_context *ctx );
+
+/**
* \brief Gracefully shutdown the connection and free associated data
*
* \param ctx The context to free
diff --git a/thirdparty/mbedtls/include/mbedtls/nist_kw.h b/thirdparty/mbedtls/include/mbedtls/nist_kw.h
index 9435656994..7f3e64a525 100644
--- a/thirdparty/mbedtls/include/mbedtls/nist_kw.h
+++ b/thirdparty/mbedtls/include/mbedtls/nist_kw.h
@@ -17,13 +17,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -36,39 +30,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_NIST_KW_H
#define MBEDTLS_NIST_KW_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "cipher.h"
+#include "mbedtls/cipher.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h
index 6d3d3ee0f3..1c39186a49 100644
--- a/thirdparty/mbedtls/include/mbedtls/oid.h
+++ b/thirdparty/mbedtls/include/mbedtls/oid.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,52 +18,27 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_OID_H
#define MBEDTLS_OID_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "asn1.h"
-#include "pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/pk.h"
#include <stddef.h>
#if defined(MBEDTLS_CIPHER_C)
-#include "cipher.h"
+#include "mbedtls/cipher.h"
#endif
#if defined(MBEDTLS_MD_C)
-#include "md.h"
-#endif
-
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
-#include "x509.h"
+#include "mbedtls/md.h"
#endif
/** OID is not found. */
@@ -77,6 +46,28 @@
/** output buffer is too small */
#define MBEDTLS_ERR_OID_BUF_TOO_SMALL -0x000B
+/* This is for the benefit of X.509, but defined here in order to avoid
+ * having a "backwards" include of x.509.h here */
+/*
+ * X.509 extension types (internal, arbitrary values for bitsets)
+ */
+#define MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
+#define MBEDTLS_OID_X509_EXT_KEY_USAGE (1 << 2)
+#define MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
+#define MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS (1 << 4)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME (1 << 5)
+#define MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME (1 << 6)
+#define MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
+#define MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS (1 << 8)
+#define MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS (1 << 9)
+#define MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
+#define MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
+#define MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
+#define MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
+#define MBEDTLS_OID_X509_EXT_FRESHEST_CRL (1 << 14)
+#define MBEDTLS_OID_X509_EXT_NS_CERT_TYPE (1 << 16)
+
/*
* Top level OID tuples
*/
@@ -131,7 +122,8 @@
* { iso(1) identified-organization(3) dod(6) internet(1)
* security(5) mechanisms(5) pkix(7) }
*/
-#define MBEDTLS_OID_PKIX MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01\x05\x05\x07"
+#define MBEDTLS_OID_INTERNET MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_ORG_DOD "\x01"
+#define MBEDTLS_OID_PKIX MBEDTLS_OID_INTERNET "\x05\x05\x07"
/*
* Arc for standard naming attributes
@@ -177,6 +169,11 @@
#define MBEDTLS_OID_FRESHEST_CRL MBEDTLS_OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */
/*
+ * Certificate policies
+ */
+#define MBEDTLS_OID_ANY_POLICY MBEDTLS_OID_CERTIFICATE_POLICIES "\x00" /**< anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } */
+
+/*
* Netscape certificate extensions
*/
#define MBEDTLS_OID_NS_CERT MBEDTLS_OID_NETSCAPE "\x01"
@@ -210,6 +207,16 @@
#define MBEDTLS_OID_TIME_STAMPING MBEDTLS_OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */
#define MBEDTLS_OID_OCSP_SIGNING MBEDTLS_OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */
+/**
+ * Wi-SUN Alliance Field Area Network
+ * { iso(1) identified-organization(3) dod(6) internet(1)
+ * private(4) enterprise(1) WiSUN(45605) FieldAreaNetwork(1) }
+ */
+#define MBEDTLS_OID_WISUN_FAN MBEDTLS_OID_INTERNET "\x04\x01\x82\xe4\x25\x01"
+
+#define MBEDTLS_OID_ON MBEDTLS_OID_PKIX "\x08" /**< id-on OBJECT IDENTIFIER ::= { id-pkix 8 } */
+#define MBEDTLS_OID_ON_HW_MODULE_NAME MBEDTLS_OID_ON "\x04" /**< id-on-hardwareModuleName OBJECT IDENTIFIER ::= { id-on 4 } */
+
/*
* PKCS definition OIDs
*/
@@ -255,6 +262,8 @@
#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */
+#define MBEDTLS_OID_DIGEST_ALG_RIPEMD160 MBEDTLS_OID_TELETRUST "\x03\x02\x01" /**< id-ripemd160 OBJECT IDENTIFIER :: { iso(1) identified-organization(3) teletrust(36) algorithm(3) hashAlgorithm(2) ripemd160(1) } */
+
#define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */
#define MBEDTLS_OID_HMAC_SHA224 MBEDTLS_OID_RSA_COMPANY "\x02\x08" /**< id-hmacWithSHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 8 } */
@@ -451,7 +460,6 @@ typedef struct mbedtls_oid_descriptor_t
*/
int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_buf *oid );
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
/**
* \brief Translate an X.509 extension OID into local values
*
@@ -461,7 +469,6 @@ int mbedtls_oid_get_numeric_string( char *buf, size_t size, const mbedtls_asn1_b
* \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
*/
int mbedtls_oid_get_x509_ext_type( const mbedtls_asn1_buf *oid, int *ext_type );
-#endif
/**
* \brief Translate an X.509 attribute type OID into the short name
@@ -588,6 +595,16 @@ int mbedtls_oid_get_md_hmac( const mbedtls_asn1_buf *oid, mbedtls_md_type_t *md_
int mbedtls_oid_get_extended_key_usage( const mbedtls_asn1_buf *oid, const char **desc );
/**
+ * \brief Translate certificate policies OID into description
+ *
+ * \param oid OID to use
+ * \param desc place to store string pointer
+ *
+ * \return 0 if successful, or MBEDTLS_ERR_OID_NOT_FOUND
+ */
+int mbedtls_oid_get_certificate_policies( const mbedtls_asn1_buf *oid, const char **desc );
+
+/**
* \brief Translate md_type into hash algorithm OID
*
* \param md_alg message digest algorithm
diff --git a/thirdparty/mbedtls/include/mbedtls/padlock.h b/thirdparty/mbedtls/include/mbedtls/padlock.h
index 83d6f4a5ca..624d02dff5 100644
--- a/thirdparty/mbedtls/include/mbedtls/padlock.h
+++ b/thirdparty/mbedtls/include/mbedtls/padlock.h
@@ -9,13 +9,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -28,38 +22,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PADLOCK_H
#define MBEDTLS_PADLOCK_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "aes.h"
+#include "mbedtls/aes.h"
/** Input data should be aligned. */
#define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030
diff --git a/thirdparty/mbedtls/include/mbedtls/pem.h b/thirdparty/mbedtls/include/mbedtls/pem.h
index bfa3059559..dfb4ff218e 100644
--- a/thirdparty/mbedtls/include/mbedtls/pem.h
+++ b/thirdparty/mbedtls/include/mbedtls/pem.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PEM_H
#define MBEDTLS_PEM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/pk.h b/thirdparty/mbedtls/include/mbedtls/pk.h
index 1f303396ca..8f2abf2a60 100644
--- a/thirdparty/mbedtls/include/mbedtls/pk.h
+++ b/thirdparty/mbedtls/include/mbedtls/pk.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,50 +18,33 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PK_H
#define MBEDTLS_PK_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "md.h"
+#include "mbedtls/md.h"
#if defined(MBEDTLS_RSA_C)
-#include "rsa.h"
+#include "mbedtls/rsa.h"
#endif
#if defined(MBEDTLS_ECP_C)
-#include "ecp.h"
+#include "mbedtls/ecp.h"
#endif
#if defined(MBEDTLS_ECDSA_C)
-#include "ecdsa.h"
+#include "mbedtls/ecdsa.h"
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
@@ -123,6 +100,7 @@ typedef enum {
MBEDTLS_PK_ECDSA,
MBEDTLS_PK_RSA_ALT,
MBEDTLS_PK_RSASSA_PSS,
+ MBEDTLS_PK_OPAQUE,
} mbedtls_pk_type_t;
/**
@@ -137,6 +115,58 @@ typedef struct mbedtls_pk_rsassa_pss_options
} mbedtls_pk_rsassa_pss_options;
/**
+ * \brief Maximum size of a signature made by mbedtls_pk_sign().
+ */
+/* We need to set MBEDTLS_PK_SIGNATURE_MAX_SIZE to the maximum signature
+ * size among the supported signature types. Do it by starting at 0,
+ * then incrementally increasing to be large enough for each supported
+ * signature mechanism.
+ *
+ * The resulting value can be 0, for example if MBEDTLS_ECDH_C is enabled
+ * (which allows the pk module to be included) but neither MBEDTLS_ECDSA_C
+ * nor MBEDTLS_RSA_C nor any opaque signature mechanism (PSA or RSA_ALT).
+ */
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE 0
+
+#if ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_PK_RSA_ALT_SUPPORT) ) && \
+ MBEDTLS_MPI_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* For RSA, the signature can be as large as the bignum module allows.
+ * For RSA_ALT, the signature size is not necessarily tied to what the
+ * bignum module can do, but in the absence of any specific setting,
+ * we use that (rsa_alt_sign_wrap in pk_wrap will check). */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
+#endif
+
+#if defined(MBEDTLS_ECDSA_C) && \
+ MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* For ECDSA, the ecdsa module exports a constant for the maximum
+ * signature size. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
+#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#if PSA_SIGNATURE_MAX_SIZE > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* PSA_SIGNATURE_MAX_SIZE is the maximum size of a signature made
+ * through the PSA API in the PSA representation. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE PSA_SIGNATURE_MAX_SIZE
+#endif
+
+#if PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 > MBEDTLS_PK_SIGNATURE_MAX_SIZE
+/* The Mbed TLS representation is different for ECDSA signatures:
+ * PSA uses the raw concatenation of r and s,
+ * whereas Mbed TLS uses the ASN.1 representation (SEQUENCE of two INTEGERs).
+ * Add the overhead of ASN.1: up to (1+2) + 2 * (1+2+1) for the
+ * types, lengths (represented by up to 2 bytes), and potential leading
+ * zeros of the INTEGERs and the SEQUENCE. */
+#undef MBEDTLS_PK_SIGNATURE_MAX_SIZE
+#define MBEDTLS_PK_SIGNATURE_MAX_SIZE ( PSA_VENDOR_ECDSA_SIGNATURE_MAX_SIZE + 11 )
+#endif
+#endif /* defined(MBEDTLS_USE_PSA_CRYPTO) */
+
+/**
* \brief Types for interfacing with the debug module
*/
typedef enum
@@ -249,6 +279,11 @@ void mbedtls_pk_init( mbedtls_pk_context *ctx );
*
* \param ctx The context to clear. It must have been initialized.
* If this is \c NULL, this function does nothing.
+ *
+ * \note For contexts that have been set up with
+ * mbedtls_pk_setup_opaque(), this does not free the underlying
+ * PSA key and you still need to call psa_destroy_key()
+ * independently if you want to destroy that key.
*/
void mbedtls_pk_free( mbedtls_pk_context *ctx );
@@ -287,6 +322,39 @@ void mbedtls_pk_restart_free( mbedtls_pk_restart_ctx *ctx );
*/
int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Initialize a PK context to wrap a PSA key.
+ *
+ * \note This function replaces mbedtls_pk_setup() for contexts
+ * that wrap a (possibly opaque) PSA key instead of
+ * storing and manipulating the key material directly.
+ *
+ * \param ctx The context to initialize. It must be empty (type NONE).
+ * \param key The PSA key to wrap, which must hold an ECC key pair
+ * (see notes below).
+ *
+ * \note The wrapped key must remain valid as long as the
+ * wrapping PK context is in use, that is at least between
+ * the point this function is called and the point
+ * mbedtls_pk_free() is called on this context. The wrapped
+ * key might then be independently used or destroyed.
+ *
+ * \note This function is currently only available for ECC key
+ * pairs (that is, ECC keys containing private key material).
+ * Support for other key types may be added later.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA on invalid input
+ * (context already used, invalid key identifier).
+ * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the key is not an
+ * ECC key pair.
+ * \return #MBEDTLS_ERR_PK_ALLOC_FAILED on allocation failure.
+ */
+int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
+ const psa_key_id_t key );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/**
* \brief Initialize an RSA-alt context
@@ -440,8 +508,13 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
* \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes)
- * \param sig Place to write the signature
- * \param sig_len Number of bytes written
+ * \param sig Place to write the signature.
+ * It must have enough room for the signature.
+ * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
+ * You may use a smaller buffer if it is large enough
+ * given the key type.
+ * \param sig_len On successful return,
+ * the number of bytes written to \p sig.
* \param f_rng RNG function
* \param p_rng RNG parameter
*
@@ -456,10 +529,6 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
*
* \note For RSA, md_alg may be MBEDTLS_MD_NONE if hash_len != 0.
* For ECDSA, md_alg may never be MBEDTLS_MD_NONE.
- *
- * \note In order to ensure enough space for the signature, the
- * \p sig buffer size must be of at least
- * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
*/
int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@@ -474,22 +543,23 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
* \c mbedtls_ecp_set_max_ops() to reduce blocking for ECC
* operations. For RSA, same as \c mbedtls_pk_sign().
*
- * \note In order to ensure enough space for the signature, the
- * \p sig buffer size must be of at least
- * `max(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)` bytes.
- *
* \param ctx The PK context to use. It must have been set up
* with a private key.
- * \param md_alg Hash algorithm used (see notes)
+ * \param md_alg Hash algorithm used (see notes for mbedtls_pk_sign())
* \param hash Hash of the message to sign
- * \param hash_len Hash length or 0 (see notes)
- * \param sig Place to write the signature
- * \param sig_len Number of bytes written
+ * \param hash_len Hash length or 0 (see notes for mbedtls_pk_sign())
+ * \param sig Place to write the signature.
+ * It must have enough room for the signature.
+ * #MBEDTLS_PK_SIGNATURE_MAX_SIZE is always enough.
+ * You may use a smaller buffer if it is large enough
+ * given the key type.
+ * \param sig_len On successful return,
+ * the number of bytes written to \p sig.
* \param f_rng RNG function
* \param p_rng RNG parameter
* \param rs_ctx Restart context (NULL to disable restart)
*
- * \return See \c mbedtls_pk_sign(), or
+ * \return See \c mbedtls_pk_sign().
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
* operations was reached: see \c mbedtls_ecp_set_max_ops().
*/
@@ -549,7 +619,11 @@ int mbedtls_pk_encrypt( mbedtls_pk_context *ctx,
* \param pub Context holding a public key.
* \param prv Context holding a private (and public) key.
*
- * \return 0 on success or MBEDTLS_ERR_PK_BAD_INPUT_DATA
+ * \return \c 0 on success (keys were checked and match each other).
+ * \return #MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE if the keys could not
+ * be checked - in that case they may or may not match.
+ * \return #MBEDTLS_ERR_PK_BAD_INPUT_DATA if a context is invalid.
+ * \return Another non-zero value if the keys do not match.
*/
int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv );
@@ -788,6 +862,32 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n );
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Turn an EC key into an opaque one.
+ *
+ * \warning This is a temporary utility function for tests. It might
+ * change or be removed at any time without notice.
+ *
+ * \note Only ECDSA keys are supported so far. Signing with the
+ * specified hash is the only allowed use of that key.
+ *
+ * \param pk Input: the EC key to import to a PSA key.
+ * Output: a PK context wrapping that PSA key.
+ * \param key Output: a PSA key identifier.
+ * It's the caller's responsibility to call
+ * psa_destroy_key() on that key identifier after calling
+ * mbedtls_pk_free() on the PK context.
+ * \param hash_alg The hash algorithm to allow for use with that key.
+ *
+ * \return \c 0 if successful.
+ * \return An Mbed TLS error code otherwise.
+ */
+int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
+ psa_key_id_t *key,
+ psa_algorithm_t hash_alg );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/pk_internal.h b/thirdparty/mbedtls/include/mbedtls/pk_internal.h
index 3f84cdf748..47f7767700 100644
--- a/thirdparty/mbedtls/include/mbedtls/pk_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/pk_internal.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,39 +18,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PK_WRAP_H
#define MBEDTLS_PK_WRAP_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "pk.h"
+#include "mbedtls/pk.h"
struct mbedtls_pk_info_t
{
@@ -160,4 +133,8 @@ extern const mbedtls_pk_info_t mbedtls_ecdsa_info;
extern const mbedtls_pk_info_t mbedtls_rsa_alt_info;
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+extern const mbedtls_pk_info_t mbedtls_pk_opaque_info;
+#endif
+
#endif /* MBEDTLS_PK_WRAP_H */
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs11.h b/thirdparty/mbedtls/include/mbedtls/pkcs11.h
index 3874d4a05e..3530ee1688 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs11.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs11.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,40 +20,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PKCS11_H
#define MBEDTLS_PKCS11_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_PKCS11_C)
-#include "x509_crt.h"
+#include "mbedtls/x509_crt.h"
#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
@@ -72,6 +45,8 @@
extern "C" {
#endif
+#if defined(MBEDTLS_DEPRECATED_REMOVED)
+
/**
* Context for PKCS #11 private keys.
*/
@@ -81,47 +56,71 @@ typedef struct mbedtls_pkcs11_context
int len;
} mbedtls_pkcs11_context;
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
/**
* Initialize a mbedtls_pkcs11_context.
* (Just making memory references valid.)
+ *
+ * \deprecated This function is deprecated and will be removed in a
+ * future version of the library.
*/
-void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx );
+MBEDTLS_DEPRECATED void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx );
/**
* Fill in a mbed TLS certificate, based on the given PKCS11 helper certificate.
*
+ * \deprecated This function is deprecated and will be removed in a
+ * future version of the library.
+ *
* \param cert X.509 certificate to fill
* \param pkcs11h_cert PKCS #11 helper certificate
*
* \return 0 on success.
*/
-int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert );
+MBEDTLS_DEPRECATED int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert,
+ pkcs11h_certificate_t pkcs11h_cert );
/**
* Set up a mbedtls_pkcs11_context storing the given certificate. Note that the
* mbedtls_pkcs11_context will take over control of the certificate, freeing it when
* done.
*
+ * \deprecated This function is deprecated and will be removed in a
+ * future version of the library.
+ *
* \param priv_key Private key structure to fill.
* \param pkcs11_cert PKCS #11 helper certificate
*
* \return 0 on success
*/
-int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key,
- pkcs11h_certificate_t pkcs11_cert );
+MBEDTLS_DEPRECATED int mbedtls_pkcs11_priv_key_bind(
+ mbedtls_pkcs11_context *priv_key,
+ pkcs11h_certificate_t pkcs11_cert );
/**
* Free the contents of the given private key context. Note that the structure
* itself is not freed.
*
+ * \deprecated This function is deprecated and will be removed in a
+ * future version of the library.
+ *
* \param priv_key Private key structure to cleanup
*/
-void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key );
+MBEDTLS_DEPRECATED void mbedtls_pkcs11_priv_key_free(
+ mbedtls_pkcs11_context *priv_key );
/**
* \brief Do an RSA private key decrypt, then remove the message
* padding
*
+ * \deprecated This function is deprecated and will be removed in a future
+ * version of the library.
+ *
* \param ctx PKCS #11 context
* \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
* \param input buffer holding the encrypted data
@@ -135,15 +134,18 @@ void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key );
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
* an error is thrown.
*/
-int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
- int mode, size_t *olen,
- const unsigned char *input,
- unsigned char *output,
- size_t output_max_len );
+MBEDTLS_DEPRECATED int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input,
+ unsigned char *output,
+ size_t output_max_len );
/**
* \brief Do a private RSA to sign a message digest
*
+ * \deprecated This function is deprecated and will be removed in a future
+ * version of the library.
+ *
* \param ctx PKCS #11 context
* \param mode must be MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's signature
* \param md_alg a MBEDTLS_MD_XXX (use MBEDTLS_MD_NONE for signing raw data)
@@ -157,28 +159,58 @@ int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx,
* \note The "sig" buffer must be as large as the size
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
*/
-int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
- int mode,
- mbedtls_md_type_t md_alg,
- unsigned int hashlen,
- const unsigned char *hash,
- unsigned char *sig );
+MBEDTLS_DEPRECATED int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig );
/**
* SSL/TLS wrappers for PKCS#11 functions
+ *
+ * \deprecated This function is deprecated and will be removed in a future
+ * version of the library.
*/
-static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen,
- const unsigned char *input, unsigned char *output,
- size_t output_max_len )
+MBEDTLS_DEPRECATED static inline int mbedtls_ssl_pkcs11_decrypt( void *ctx,
+ int mode, size_t *olen,
+ const unsigned char *input, unsigned char *output,
+ size_t output_max_len )
{
return mbedtls_pkcs11_decrypt( (mbedtls_pkcs11_context *) ctx, mode, olen, input, output,
output_max_len );
}
-static inline int mbedtls_ssl_pkcs11_sign( void *ctx,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
- int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
- const unsigned char *hash, unsigned char *sig )
+/**
+ * \brief This function signs a message digest using RSA.
+ *
+ * \deprecated This function is deprecated and will be removed in a future
+ * version of the library.
+ *
+ * \param ctx The PKCS #11 context.
+ * \param f_rng The RNG function. This parameter is unused.
+ * \param p_rng The RNG context. This parameter is unused.
+ * \param mode The operation to run. This must be set to
+ * MBEDTLS_RSA_PRIVATE, for compatibility with rsa.c's
+ * signature.
+ * \param md_alg The message digest algorithm. One of the MBEDTLS_MD_XXX
+ * must be passed to this function and MBEDTLS_MD_NONE can be
+ * used for signing raw data.
+ * \param hashlen The message digest length (for MBEDTLS_MD_NONE only).
+ * \param hash The buffer holding the message digest.
+ * \param sig The buffer that will hold the ciphertext.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return A non-zero error code on failure.
+ *
+ * \note The \p sig buffer must be as large as the size of
+ * <code>ctx->N</code>. For example, 128 bytes if RSA-1024 is
+ * used.
+ */
+MBEDTLS_DEPRECATED static inline int mbedtls_ssl_pkcs11_sign( void *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
+ int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,
+ const unsigned char *hash, unsigned char *sig )
{
((void) f_rng);
((void) p_rng);
@@ -186,11 +218,25 @@ static inline int mbedtls_ssl_pkcs11_sign( void *ctx,
hashlen, hash, sig );
}
-static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx )
+/**
+ * This function gets the length of the private key.
+ *
+ * \deprecated This function is deprecated and will be removed in a future
+ * version of the library.
+ *
+ * \param ctx The PKCS #11 context.
+ *
+ * \return The length of the private key.
+ */
+MBEDTLS_DEPRECATED static inline size_t mbedtls_ssl_pkcs11_key_len( void *ctx )
{
return ( (mbedtls_pkcs11_context *) ctx )->len;
}
+#undef MBEDTLS_DEPRECATED
+
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs12.h b/thirdparty/mbedtls/include/mbedtls/pkcs12.h
index 2f85aab7ef..d9e85b1d12 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs12.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs12.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,40 +18,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PKCS12_H
#define MBEDTLS_PKCS12_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "md.h"
-#include "cipher.h"
-#include "asn1.h"
+#include "mbedtls/md.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/asn1.h"
#include <stddef.h>
diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs5.h b/thirdparty/mbedtls/include/mbedtls/pkcs5.h
index 9b97d62341..696930f745 100644
--- a/thirdparty/mbedtls/include/mbedtls/pkcs5.h
+++ b/thirdparty/mbedtls/include/mbedtls/pkcs5.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,39 +20,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PKCS5_H
#define MBEDTLS_PKCS5_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "asn1.h"
-#include "md.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/md.h"
#include <stddef.h>
#include <stdint.h>
diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h
index f6ccd1cd82..bdef07498d 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform.h
@@ -14,13 +14,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -33,39 +27,18 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PLATFORM_H
#define MBEDTLS_PLATFORM_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_HAVE_TIME)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
#endif
/** Hardware accelerator failed */
@@ -85,17 +58,33 @@ extern "C" {
* \{
*/
+/* The older Microsoft Windows common runtime provides non-conforming
+ * implementations of some standard library functions, including snprintf
+ * and vsnprintf. This affects MSVC and MinGW builds.
+ */
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _MSC_VER <= 1900)
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF
+#define MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF
+#endif
+
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< The default \c snprintf function to use. */
#else
#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< The default \c snprintf function to use. */
#endif
#endif
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF mbedtls_platform_win32_vsnprintf /**< The default \c vsnprintf function to use. */
+#else
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF vsnprintf /**< The default \c vsnprintf function to use. */
+#endif
+#endif
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< The default \c printf function to use. */
#endif
@@ -231,7 +220,7 @@ int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) );
* - however it is acceptable to return -1 instead of the required length when
* the destination buffer is too short.
*/
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
/* For Windows (inc. MSYS2), we provide our own fixed implementation */
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... );
#endif
@@ -258,6 +247,42 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
/*
+ * The function pointers for vsnprintf
+ *
+ * The vsnprintf implementation should conform to C99:
+ * - it *must* always correctly zero-terminate the buffer
+ * (except when n == 0, then it must leave the buffer untouched)
+ * - however it is acceptable to return -1 instead of the required length when
+ * the destination buffer is too short.
+ */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
+/* For Older Windows (inc. MSYS2), we provide our own fixed implementation */
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg );
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#include <stdarg.h>
+extern int (*mbedtls_vsnprintf)( char * s, size_t n, const char * format, va_list arg );
+
+/**
+ * \brief Set your own snprintf function pointer
+ *
+ * \param vsnprintf_func The \c vsnprintf function implementation
+ *
+ * \return \c 0
+ */
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format, va_list arg ) );
+#else /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_MACRO)
+#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO
+#else
+#define mbedtls_vsnprintf vsnprintf
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_MACRO */
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
+/*
* The function pointers for exit
*/
#if defined(MBEDTLS_PLATFORM_EXIT_ALT)
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_time.h b/thirdparty/mbedtls/include/mbedtls/platform_time.h
index e132f6a688..7e7daab692 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_time.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_time.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PLATFORM_TIME_H
#define MBEDTLS_PLATFORM_TIME_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/platform_util.h b/thirdparty/mbedtls/include/mbedtls/platform_util.h
index 426afaf040..f982db8c01 100644
--- a/thirdparty/mbedtls/include/mbedtls/platform_util.h
+++ b/thirdparty/mbedtls/include/mbedtls/platform_util.h
@@ -6,13 +6,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,40 +19,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_PLATFORM_UTIL_H
#define MBEDTLS_PLATFORM_UTIL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#include <stddef.h>
#if defined(MBEDTLS_HAVE_TIME_DATE)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
#include <time.h>
#endif /* MBEDTLS_HAVE_TIME_DATE */
@@ -159,6 +132,95 @@ MBEDTLS_DEPRECATED typedef int mbedtls_deprecated_numeric_constant_t;
#endif /* MBEDTLS_DEPRECATED_WARNING */
#endif /* MBEDTLS_DEPRECATED_REMOVED */
+/* Implementation of the check-return facility.
+ * See the user documentation in config.h.
+ *
+ * Do not use this macro directly to annotate function: instead,
+ * use one of MBEDTLS_CHECK_RETURN_CRITICAL or MBEDTLS_CHECK_RETURN_TYPICAL
+ * depending on how important it is to check the return value.
+ */
+#if !defined(MBEDTLS_CHECK_RETURN)
+#if defined(__GNUC__)
+#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__))
+#elif defined(_MSC_VER) && _MSC_VER >= 1700
+#include <sal.h>
+#define MBEDTLS_CHECK_RETURN _Check_return_
+#else
+#define MBEDTLS_CHECK_RETURN
+#endif
+#endif
+
+/** Critical-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be checked in all applications.
+ * Omitting the check is very likely to indicate a bug in the application
+ * and will result in a compile-time warning if #MBEDTLS_CHECK_RETURN
+ * is implemented for the compiler in use.
+ *
+ * \note The use of this macro is a work in progress.
+ * This macro may be added to more functions in the future.
+ * Such an extension is not considered an API break, provided that
+ * there are near-unavoidable circumstances under which the function
+ * can fail. For example, signature/MAC/AEAD verification functions,
+ * and functions that require a random generator, are considered
+ * return-check-critical.
+ */
+#define MBEDTLS_CHECK_RETURN_CRITICAL MBEDTLS_CHECK_RETURN
+
+/** Ordinary-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that its return value should be generally be checked in portable
+ * applications. Omitting the check will result in a compile-time warning if
+ * #MBEDTLS_CHECK_RETURN is implemented for the compiler in use and
+ * #MBEDTLS_CHECK_RETURN_WARNING is enabled in the compile-time configuration.
+ *
+ * You can use #MBEDTLS_IGNORE_RETURN to explicitly ignore the return value
+ * of a function that is annotated with #MBEDTLS_CHECK_RETURN.
+ *
+ * \note The use of this macro is a work in progress.
+ * This macro will be added to more functions in the future.
+ * Eventually this should appear before most functions returning
+ * an error code (as \c int in the \c mbedtls_xxx API or
+ * as ::psa_status_t in the \c psa_xxx API).
+ */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+#define MBEDTLS_CHECK_RETURN_TYPICAL MBEDTLS_CHECK_RETURN
+#else
+#define MBEDTLS_CHECK_RETURN_TYPICAL
+#endif
+
+/** Benign-failure function
+ *
+ * This macro appearing at the beginning of the declaration of a function
+ * indicates that it is rarely useful to check its return value.
+ *
+ * This macro has an empty expansion. It exists for documentation purposes:
+ * a #MBEDTLS_CHECK_RETURN_OPTIONAL annotation indicates that the function
+ * has been analyzed for return-check usefuless, whereas the lack of
+ * an annotation indicates that the function has not been analyzed and its
+ * return-check usefulness is unknown.
+ */
+#define MBEDTLS_CHECK_RETURN_OPTIONAL
+
+/** \def MBEDTLS_IGNORE_RETURN
+ *
+ * Call this macro with one argument, a function call, to suppress a warning
+ * from #MBEDTLS_CHECK_RETURN due to that function call.
+ */
+#if !defined(MBEDTLS_IGNORE_RETURN)
+/* GCC doesn't silence the warning with just (void)(result).
+ * (void)!(result) is known to work up at least up to GCC 10, as well
+ * as with Clang and MSVC.
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Non_002dbugs.html
+ * https://stackoverflow.com/questions/40576003/ignoring-warning-wunused-result
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425#c34
+ */
+#define MBEDTLS_IGNORE_RETURN(result) ( (void) !( result ) )
+#endif
+
/**
* \brief Securely zeroize a buffer
*
diff --git a/thirdparty/mbedtls/include/mbedtls/poly1305.h b/thirdparty/mbedtls/include/mbedtls/poly1305.h
index ea69dba576..a69ede98b5 100644
--- a/thirdparty/mbedtls/include/mbedtls/poly1305.h
+++ b/thirdparty/mbedtls/include/mbedtls/poly1305.h
@@ -14,13 +14,7 @@
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -33,34 +27,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_POLY1305_H
#define MBEDTLS_POLY1305_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h
index 415c897530..63270d1239 100644
--- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h
+++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_RIPEMD160_H
#define MBEDTLS_RIPEMD160_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -83,7 +56,7 @@ typedef struct mbedtls_ripemd160_context
mbedtls_ripemd160_context;
#else /* MBEDTLS_RIPEMD160_ALT */
-#include "ripemd160.h"
+#include "ripemd160_alt.h"
#endif /* MBEDTLS_RIPEMD160_ALT */
/**
diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h
index 9b5da67e1b..3c481e12a1 100644
--- a/thirdparty/mbedtls/include/mbedtls/rsa.h
+++ b/thirdparty/mbedtls/include/mbedtls/rsa.h
@@ -11,13 +11,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -30,42 +24,21 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_RSA_H
#define MBEDTLS_RSA_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
-#include "md.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/md.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
/*
@@ -641,7 +614,8 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
* \param ilen The length of the plaintext in Bytes.
* \param input The input data to encrypt. This must be a readable
- * buffer of size \p ilen Bytes. This must not be \c NULL.
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
* \param output The output buffer. This must be a writable buffer
* of length \c ctx->len Bytes. For example, \c 256 Bytes
* for an 2048-bit RSA modulus.
@@ -681,7 +655,8 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
* #MBEDTLS_RSA_PUBLIC or #MBEDTLS_RSA_PRIVATE (deprecated).
* \param ilen The length of the plaintext in Bytes.
* \param input The input data to encrypt. This must be a readable
- * buffer of size \p ilen Bytes. This must not be \c NULL.
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
* \param output The output buffer. This must be a writable buffer
* of length \c ctx->len Bytes. For example, \c 256 Bytes
* for an 2048-bit RSA modulus.
@@ -725,7 +700,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
* \param label_len The length of the label in Bytes.
* \param ilen The length of the plaintext buffer \p input in Bytes.
* \param input The input data to encrypt. This must be a readable
- * buffer of size \p ilen Bytes. This must not be \c NULL.
+ * buffer of size \p ilen Bytes. It may be \c NULL if
+ * `ilen == 0`.
* \param output The output buffer. This must be a writable buffer
* of length \c ctx->len Bytes. For example, \c 256 Bytes
* for an 2048-bit RSA modulus.
@@ -1011,12 +987,69 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
* \brief This function performs a PKCS#1 v2.1 PSS signature
* operation (RSASSA-PSS-SIGN).
*
- * \note The \p hash_id in the RSA context is the one used for the
- * encoding. \p md_alg in the function call is the type of hash
- * that is encoded. According to <em>RFC-3447: Public-Key
+ * \note The \c hash_id set in \p ctx (when calling
+ * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding()
+ * afterwards) selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
+ * Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>.
+ *
+ * \note This function enforces that the provided salt length complies
+ * with FIPS 186-4 §5.5 (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1
+ * step 3. The constraint is that the hash length plus the salt
+ * length plus 2 bytes must be at most the key length. If this
+ * constraint is not met, this function returns
+ * #MBEDTLS_ERR_RSA_BAD_INPUT_DATA.
+ *
+ * \param ctx The initialized RSA context to use.
+ * \param f_rng The RNG function. It must not be \c NULL.
+ * \param p_rng The RNG context to be passed to \p f_rng. This may be \c NULL
+ * if \p f_rng doesn't need a context argument.
+ * \param md_alg The message-digest algorithm used to hash the original data.
+ * Use #MBEDTLS_MD_NONE for signing raw data.
+ * \param hashlen The length of the message digest.
+ * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * \param hash The buffer holding the message digest or raw data.
+ * If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
+ * buffer of length \p hashlen Bytes. If \p md_alg is not
+ * #MBEDTLS_MD_NONE, it must be a readable buffer of length
+ * the size of the hash corresponding to \p md_alg.
+ * \param saltlen The length of the salt that should be used.
+ * If passed #MBEDTLS_RSA_SALT_LEN_ANY, the function will use
+ * the largest possible salt length up to the hash length,
+ * which is the largest permitted by some standards including
+ * FIPS 186-4 §5.5.
+ * \param sig The buffer to hold the signature. This must be a writable
+ * buffer of length \c ctx->len Bytes. For example, \c 256 Bytes
+ * for an 2048-bit RSA modulus. A buffer length of
+ * #MBEDTLS_MPI_MAX_SIZE is always safe.
+ *
+ * \return \c 0 if the signing operation was successful.
+ * \return An \c MBEDTLS_ERR_RSA_XXX error code on failure.
+ */
+int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ int saltlen,
+ unsigned char *sig );
+
+/**
+ * \brief This function performs a PKCS#1 v2.1 PSS signature
+ * operation (RSASSA-PSS-SIGN).
+ *
+ * \note The \c hash_id set in \p ctx (when calling
+ * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding()
+ * afterwards) selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
* Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- * Specifications</em> it is advised to keep both hashes the
- * same.
+ * Specifications</em>.
*
* \note This function always uses the maximum possible salt size,
* up to the length of the payload hash. This choice of salt
@@ -1046,7 +1079,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
* \param md_alg The message-digest algorithm used to hash the original data.
* Use #MBEDTLS_MD_NONE for signing raw data.
* \param hashlen The length of the message digest.
- * Ths is only used if \p md_alg is #MBEDTLS_MD_NONE.
+ * This is only used if \p md_alg is #MBEDTLS_MD_NONE.
* \param hash The buffer holding the message digest or raw data.
* If \p md_alg is #MBEDTLS_MD_NONE, this must be a readable
* buffer of length \p hashlen Bytes. If \p md_alg is not
@@ -1172,16 +1205,15 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
* \brief This function performs a PKCS#1 v2.1 PSS verification
* operation (RSASSA-PSS-VERIFY).
*
- * The hash function for the MGF mask generating function
- * is that specified in the RSA context.
- *
- * \note The \p hash_id in the RSA context is the one used for the
- * verification. \p md_alg in the function call is the type of
- * hash that is verified. According to <em>RFC-3447: Public-Key
+ * \note The \c hash_id set in \p ctx (when calling
+ * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding()
+ * afterwards) selects the hash used for the
+ * encoding operation and for the mask generation function
+ * (MGF1). For more details on the encoding operation and the
+ * mask generation function, consult <em>RFC-3447: Public-Key
* Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography
- * Specifications</em> it is advised to keep both hashes the
- * same. If \p hash_id in the RSA context is unset,
- * the \p md_alg from the function call is used.
+ * Specifications</em>. If the \c hash_id set in \p ctx is
+ * #MBEDTLS_MD_NONE, the \p md_alg parameter is used.
*
* \deprecated It is deprecated and discouraged to call this function
* in #MBEDTLS_RSA_PRIVATE mode. Future versions of the library
@@ -1229,13 +1261,12 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
* \brief This function performs a PKCS#1 v2.1 PSS verification
* operation (RSASSA-PSS-VERIFY).
*
- * The hash function for the MGF mask generating function
- * is that specified in \p mgf1_hash_id.
- *
* \note The \p sig buffer must be as large as the size
* of \p ctx->N. For example, 128 Bytes if RSA-1024 is used.
*
- * \note The \p hash_id in the RSA context is ignored.
+ * \note The \c hash_id set in \p ctx (when calling
+ * mbedtls_rsa_init() or by calling mbedtls_rsa_set_padding()
+ * afterwards) is ignored.
*
* \param ctx The initialized RSA public key context to use.
* \param f_rng The RNG function to use. If \p mode is #MBEDTLS_RSA_PRIVATE,
@@ -1254,7 +1285,13 @@ int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
* buffer of length \p hashlen Bytes. If \p md_alg is not
* #MBEDTLS_MD_NONE, it must be a readable buffer of length
* the size of the hash corresponding to \p md_alg.
- * \param mgf1_hash_id The message digest used for mask generation.
+ * \param mgf1_hash_id The message digest algorithm used for the
+ * verification operation and the mask generation
+ * function (MGF1). For more details on the encoding
+ * operation and the mask generation function, consult
+ * <em>RFC-3447: Public-Key Cryptography Standards
+ * (PKCS) #1 v2.1: RSA Cryptography
+ * Specifications</em>.
* \param expected_salt_len The length of the salt used in padding. Use
* #MBEDTLS_RSA_SALT_LEN_ANY to accept any salt length.
* \param sig The buffer holding the signature. This must be a readable
diff --git a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
index 953cb7b81d..d55492bb16 100644
--- a/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/rsa_internal.h
@@ -36,13 +36,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -56,39 +50,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
#ifndef MBEDTLS_RSA_INTERNAL_H
#define MBEDTLS_RSA_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
+#include "mbedtls/bignum.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/sha1.h b/thirdparty/mbedtls/include/mbedtls/sha1.h
index 969b5dc12d..4c3251b4a1 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha1.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha1.h
@@ -12,13 +12,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -31,33 +25,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SHA1_H
#define MBEDTLS_SHA1_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/sha256.h b/thirdparty/mbedtls/include/mbedtls/sha256.h
index 68386a52a9..5b54be2142 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha256.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha256.h
@@ -8,13 +8,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -27,33 +21,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SHA256_H
#define MBEDTLS_SHA256_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/sha512.h b/thirdparty/mbedtls/include/mbedtls/sha512.h
index 353ad7a2cb..cca47c2fe6 100644
--- a/thirdparty/mbedtls/include/mbedtls/sha512.h
+++ b/thirdparty/mbedtls/include/mbedtls/sha512.h
@@ -7,13 +7,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -26,33 +20,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SHA512_H
#define MBEDTLS_SHA512_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -86,8 +59,10 @@ typedef struct mbedtls_sha512_context
uint64_t total[2]; /*!< The number of Bytes processed. */
uint64_t state[8]; /*!< The intermediate digest state. */
unsigned char buffer[128]; /*!< The data block being processed. */
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
int is384; /*!< Determines which function to use:
0: Use SHA-512, or 1: Use SHA-384. */
+#endif
}
mbedtls_sha512_context;
@@ -128,7 +103,11 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
*
* \param ctx The SHA-512 context to use. This must be initialized.
* \param is384 Determines which function to use. This must be
- * either \c for SHA-512, or \c 1 for SHA-384.
+ * either \c 0 for SHA-512, or \c 1 for SHA-384.
+ *
+ * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must
+ * be \c 0, or the function will return
+ * #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA.
*
* \return \c 0 on success.
* \return A negative error code on failure.
@@ -196,6 +175,9 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
* \param ctx The SHA-512 context to use. This must be initialized.
* \param is384 Determines which function to use. This must be either
* \c 0 for SHA-512 or \c 1 for SHA-384.
+ *
+ * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must
+ * be \c 0, or the function will fail to work.
*/
MBEDTLS_DEPRECATED void mbedtls_sha512_starts( mbedtls_sha512_context *ctx,
int is384 );
@@ -266,6 +248,10 @@ MBEDTLS_DEPRECATED void mbedtls_sha512_process(
* \param is384 Determines which function to use. This must be either
* \c 0 for SHA-512, or \c 1 for SHA-384.
*
+ * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must
+ * be \c 0, or the function will return
+ * #MBEDTLS_ERR_SHA512_BAD_INPUT_DATA.
+ *
* \return \c 0 on success.
* \return A negative error code on failure.
*/
@@ -300,6 +286,9 @@ int mbedtls_sha512_ret( const unsigned char *input,
* be a writable buffer of length \c 64 Bytes.
* \param is384 Determines which function to use. This must be either
* \c 0 for SHA-512, or \c 1 for SHA-384.
+ *
+ * \note When \c MBEDTLS_SHA512_NO_SHA384 is defined, \p is384 must
+ * be \c 0, or the function will fail to work.
*/
MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input,
size_t ilen,
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h
index cdceed8e39..209dbf6053 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,53 +18,37 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_H
#define MBEDTLS_SSL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "bignum.h"
-#include "ecp.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/ecp.h"
-#include "ssl_ciphersuites.h"
+#include "mbedtls/ssl_ciphersuites.h"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
-#include "x509_crt.h"
-#include "x509_crl.h"
+#include "mbedtls/x509_crt.h"
+#include "mbedtls/x509_crl.h"
#endif
#if defined(MBEDTLS_DHM_C)
-#include "dhm.h"
+#include "mbedtls/dhm.h"
#endif
-#if defined(MBEDTLS_ECDH_C)
-#include "ecdh.h"
+/* Adding guard for MBEDTLS_ECDSA_C to ensure no compile errors due
+ * to guards also being in ssl_srv.c and ssl_cli.c. There is a gap
+ * in functionality that access to ecdh_ctx structure is needed for
+ * MBEDTLS_ECDSA_C which does not seem correct.
+ */
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
+#include "mbedtls/ecdh.h"
#endif
#if defined(MBEDTLS_ZLIB_SUPPORT)
@@ -87,9 +65,13 @@
#endif
#if defined(MBEDTLS_HAVE_TIME)
-#include "platform_time.h"
+#include "mbedtls/platform_time.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* SSL Error codes
*/
@@ -201,6 +183,10 @@
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500
/** Internal-only message signaling that a message arrived early. */
#define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480
+/** An encrypted DTLS-frame with an unexpected CID was received. */
+#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000
+/** An operation failed due to an unexpected version or configuration. */
+#define MBEDTLS_ERR_SSL_VERSION_MISMATCH -0x5F00
/** A cryptographic operation is in progress. Try again later. */
#define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000
/** Invalid value in SSL config */
@@ -214,6 +200,7 @@
#define MBEDTLS_SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */
#define MBEDTLS_SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */
#define MBEDTLS_SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */
+#define MBEDTLS_SSL_MINOR_VERSION_4 4 /*!< TLS v1.3 (experimental) */
#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */
#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */
@@ -241,6 +228,9 @@
#define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0
#define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1
+#define MBEDTLS_SSL_CID_DISABLED 0
+#define MBEDTLS_SSL_CID_ENABLED 1
+
#define MBEDTLS_SSL_ETM_DISABLED 0
#define MBEDTLS_SSL_ETM_ENABLED 1
@@ -287,6 +277,9 @@
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1
#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0
+#define MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED 0
+#define MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED 1
+
/*
* Default range for DTLS retransmission timer value, in milliseconds.
* RFC 6347 4.2.4.1 says from 1 second to 60 seconds.
@@ -337,6 +330,25 @@
#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768
#endif
+/*
+ * Maximum length of CIDs for incoming and outgoing messages.
+ */
+#if !defined(MBEDTLS_SSL_CID_IN_LEN_MAX)
+#define MBEDTLS_SSL_CID_IN_LEN_MAX 32
+#endif
+
+#if !defined(MBEDTLS_SSL_CID_OUT_LEN_MAX)
+#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32
+#endif
+
+#if !defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY)
+#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16
+#endif
+
+#if !defined(MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY)
+#define MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY 1
+#endif
+
/* \} name SECTION: Module settings */
/*
@@ -384,6 +396,7 @@
#define MBEDTLS_SSL_MSG_ALERT 21
#define MBEDTLS_SSL_MSG_HANDSHAKE 22
#define MBEDTLS_SSL_MSG_APPLICATION_DATA 23
+#define MBEDTLS_SSL_MSG_CID 25
#define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1
#define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2
@@ -446,6 +459,8 @@
#define MBEDTLS_TLS_EXT_SIG_ALG 13
+#define MBEDTLS_TLS_EXT_USE_SRTP 14
+
#define MBEDTLS_TLS_EXT_ALPN 16
#define MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC 22 /* 0x16 */
@@ -453,6 +468,17 @@
#define MBEDTLS_TLS_EXT_SESSION_TICKET 35
+/* The value of the CID extension is still TBD as of
+ * draft-ietf-tls-dtls-connection-id-05
+ * (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05).
+ *
+ * A future minor revision of Mbed TLS may change the default value of
+ * this option to match evolving standards and usage.
+ */
+#if !defined(MBEDTLS_TLS_EXT_CID)
+#define MBEDTLS_TLS_EXT_CID 254 /* TBD */
+#endif
+
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01
@@ -531,6 +557,18 @@ typedef enum
}
mbedtls_ssl_states;
+/*
+ * The tls_prf function types.
+ */
+typedef enum
+{
+ MBEDTLS_SSL_TLS_PRF_NONE,
+ MBEDTLS_SSL_TLS_PRF_SSL3,
+ MBEDTLS_SSL_TLS_PRF_TLS1,
+ MBEDTLS_SSL_TLS_PRF_SHA384,
+ MBEDTLS_SSL_TLS_PRF_SHA256
+}
+mbedtls_tls_prf_types;
/**
* \brief Callback type: send data on the network.
*
@@ -869,11 +907,77 @@ typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48
+#if defined(MBEDTLS_SHA256_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32
+#elif defined(MBEDTLS_SHA512_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48
+#elif defined(MBEDTLS_SHA1_C)
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1
+#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20
+#else
+/* This is already checked in check_config.h, but be sure. */
+#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT."
+#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED &&
+ !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+
+#define MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH 255
+#define MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH 4
+/*
+ * For code readability use a typedef for DTLS-SRTP profiles
+ *
+ * Use_srtp extension protection profiles values as defined in
+ * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ *
+ * Reminder: if this list is expanded mbedtls_ssl_check_srtp_profile_value
+ * must be updated too.
+ */
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80 ( (uint16_t) 0x0001)
+#define MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32 ( (uint16_t) 0x0002)
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80 ( (uint16_t) 0x0005)
+#define MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32 ( (uint16_t) 0x0006)
+/* This one is not iana defined, but for code readability. */
+#define MBEDTLS_TLS_SRTP_UNSET ( (uint16_t) 0x0000)
+
+typedef uint16_t mbedtls_ssl_srtp_profile;
+
+typedef struct mbedtls_dtls_srtp_info_t
+{
+ /*! The SRTP profile that was negotiated. */
+ mbedtls_ssl_srtp_profile chosen_dtls_srtp_profile;
+ /*! The length of mki_value. */
+ uint16_t mki_len;
+ /*! The mki_value used, with max size of 256 bytes. */
+ unsigned char mki_value[MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH];
+}
+mbedtls_dtls_srtp_info;
+
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* This structure is used for storing current session data.
+ *
+ * Note: when changing this definition, we need to check and update:
+ * - in tests/suites/test_suite_ssl.function:
+ * ssl_populate_session() and ssl_serialize_session_save_load()
+ * - in library/ssl_tls.c:
+ * mbedtls_ssl_session_init() and mbedtls_ssl_session_free()
+ * mbedtls_ssl_session_save() and ssl_session_load()
+ * ssl_session_copy()
*/
struct mbedtls_ssl_session
{
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t start; /*!< starting time */
#endif
@@ -884,7 +988,15 @@ struct mbedtls_ssl_session
unsigned char master[48]; /*!< the master secret */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
- mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /*! The digest of the peer's end-CRT. This must be kept to detect CRT
+ * changes during renegotiation, mitigating the triple handshake attack. */
+ unsigned char *peer_cert_digest;
+ size_t peer_cert_digest_len;
+ mbedtls_md_type_t peer_cert_digest_type;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
uint32_t verify_result; /*!< verification result */
@@ -894,10 +1006,6 @@ struct mbedtls_ssl_session
uint32_t ticket_lifetime; /*!< ticket lifetime hint */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */
-#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
-
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
int trunc_hmac; /*!< flag for truncated hmac activation */
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
@@ -912,7 +1020,98 @@ struct mbedtls_ssl_session
*/
struct mbedtls_ssl_config
{
- /* Group items by size (largest first) to minimize padding overhead */
+ /* Group items by size and reorder them to maximize usage of immediate offset access. */
+
+ /*
+ * Numerical settings (char)
+ */
+
+ unsigned char max_major_ver; /*!< max. major version used */
+ unsigned char max_minor_ver; /*!< max. minor version used */
+ unsigned char min_major_ver; /*!< min. major version used */
+ unsigned char min_minor_ver; /*!< min. minor version used */
+
+ /*
+ * Flags (could be bit-fields to save RAM, but separate bytes make
+ * the code smaller on architectures with an instruction for direct
+ * byte access).
+ */
+
+ uint8_t endpoint /*bool*/; /*!< 0: client, 1: server */
+ uint8_t transport /*bool*/; /*!< stream (TLS) or datagram (DTLS) */
+ uint8_t authmode /*2 bits*/; /*!< MBEDTLS_SSL_VERIFY_XXX */
+ /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
+ uint8_t allow_legacy_renegotiation /*2 bits*/; /*!< MBEDTLS_LEGACY_XXX */
+#if defined(MBEDTLS_ARC4_C)
+ uint8_t arc4_disabled /*bool*/; /*!< blacklist RC4 ciphersuites? */
+#endif
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ uint8_t mfl_code /*3 bits*/; /*!< desired fragment length */
+#endif
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ uint8_t encrypt_then_mac /*bool*/; /*!< negotiate encrypt-then-mac? */
+#endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ uint8_t extended_ms /*bool*/; /*!< negotiate extended master secret? */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ uint8_t anti_replay /*bool*/; /*!< detect and prevent replay? */
+#endif
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ uint8_t cbc_record_splitting /*bool*/; /*!< do cbc record splitting */
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ uint8_t disable_renegotiation /*bool*/; /*!< disable renegotiation? */
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ uint8_t trunc_hmac /*bool*/; /*!< negotiate truncated hmac? */
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ uint8_t session_tickets /*bool*/; /*!< use session tickets? */
+#endif
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+ uint8_t fallback /*bool*/; /*!< is this a fallback? */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+ uint8_t cert_req_ca_list /*bool*/; /*!< enable sending CA list in
+ Certificate Request messages? */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ uint8_t ignore_unexpected_cid /*bool*/; /*!< Determines whether DTLS
+ * record with unexpected CID
+ * should lead to failure. */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ uint8_t dtls_srtp_mki_support /*bool*/; /*!< support having mki_value
+ in the use_srtp extension? */
+#endif
+
+ /*
+ * Numerical settings (int or larger)
+ */
+
+ uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint32_t hs_timeout_min; /*!< initial value of the handshake
+ retransmission timeout (ms) */
+ uint32_t hs_timeout_max; /*!< maximum value of the handshake
+ retransmission timeout (ms) */
+#endif
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ int renego_max_records; /*!< grace period for renegotiation */
+ unsigned char renego_period[8]; /*!< value of the record counters
+ that triggers renegotiation */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ unsigned int badmac_limit; /*!< limit of records with a bad MAC */
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+ unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
+#endif
/*
* Pointers
@@ -946,7 +1145,7 @@ struct mbedtls_ssl_config
void *p_vrfy; /*!< context for X.509 verify calllback */
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
/** Callback to retrieve PSK key from identity */
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, size_t);
void *p_psk; /*!< context for PSK callback */
@@ -975,14 +1174,28 @@ struct mbedtls_ssl_config
/** Callback to export key block and master secret */
int (*f_export_keys)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t );
+ /** Callback to export key block, master secret,
+ * tls_prf and random bytes. Should replace f_export_keys */
+ int (*f_export_keys_ext)( void *, const unsigned char *,
+ const unsigned char *, size_t, size_t, size_t,
+ const unsigned char[32], const unsigned char[32],
+ mbedtls_tls_prf_types );
void *p_export_keys; /*!< context for key export callback */
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ size_t cid_len; /*!< The length of CIDs for incoming DTLS records. */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */
mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */
mbedtls_x509_crt *ca_chain; /*!< trusted CAs */
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ mbedtls_x509_crt_ca_cb_t f_ca_cb;
+ void *p_ca_cb;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -995,7 +1208,7 @@ struct mbedtls_ssl_config
void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
const int *sig_hashes; /*!< allowed signature hashes */
#endif
@@ -1008,103 +1221,52 @@ struct mbedtls_ssl_config
mbedtls_mpi dhm_G; /*!< generator for DHM */
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- unsigned char *psk; /*!< pre-shared key. This field should
- only be set via
- mbedtls_ssl_conf_psk() */
- size_t psk_len; /*!< length of the pre-shared key. This
- field should only be set via
- mbedtls_ssl_conf_psk() */
- unsigned char *psk_identity; /*!< identity for PSK negotiation. This
- field should only be set via
- mbedtls_ssl_conf_psk() */
- size_t psk_identity_len;/*!< length of identity. This field should
- only be set via
- mbedtls_ssl_conf_psk() */
-#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_id_t psk_opaque; /*!< PSA key slot holding opaque PSK. This field
+ * should only be set via
+ * mbedtls_ssl_conf_psk_opaque().
+ * If either no PSK or a raw PSK have been
+ * configured, this has value \c 0.
+ */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ unsigned char *psk; /*!< The raw pre-shared key. This field should
+ * only be set via mbedtls_ssl_conf_psk().
+ * If either no PSK or an opaque PSK
+ * have been configured, this has value NULL. */
+ size_t psk_len; /*!< The length of the raw pre-shared key.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * Its value is non-zero if and only if
+ * \c psk is not \c NULL. */
+
+ unsigned char *psk_identity; /*!< The PSK identity for PSK negotiation.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * This is set if and only if either
+ * \c psk or \c psk_opaque are set. */
+ size_t psk_identity_len;/*!< The length of PSK identity.
+ * This field should only be set via
+ * mbedtls_ssl_conf_psk().
+ * Its value is non-zero if and only if
+ * \c psk is not \c NULL or \c psk_opaque
+ * is not \c 0. */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_ALPN)
const char **alpn_list; /*!< ordered list of protocols */
#endif
- /*
- * Numerical settings (int then char)
- */
-
- uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- uint32_t hs_timeout_min; /*!< initial value of the handshake
- retransmission timeout (ms) */
- uint32_t hs_timeout_max; /*!< maximum value of the handshake
- retransmission timeout (ms) */
-#endif
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- int renego_max_records; /*!< grace period for renegotiation */
- unsigned char renego_period[8]; /*!< value of the record counters
- that triggers renegotiation */
-#endif
-
-#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- unsigned int badmac_limit; /*!< limit of records with a bad MAC */
-#endif
-
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
- unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
-#endif
-
- unsigned char max_major_ver; /*!< max. major version used */
- unsigned char max_minor_ver; /*!< max. minor version used */
- unsigned char min_major_ver; /*!< min. major version used */
- unsigned char min_minor_ver; /*!< min. minor version used */
-
- /*
- * Flags (bitfields)
- */
-
- unsigned int endpoint : 1; /*!< 0: client, 1: server */
- unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */
- unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */
- /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
- unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */
-#if defined(MBEDTLS_ARC4_C)
- unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */
-#endif
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- unsigned int mfl_code : 3; /*!< desired fragment length */
-#endif
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */
-#endif
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- unsigned int extended_ms : 1; /*!< negotiate extended master secret? */
-#endif
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- unsigned int anti_replay : 1; /*!< detect and prevent replay? */
-#endif
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */
-#endif
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */
-#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- unsigned int session_tickets : 1; /*!< use session tickets? */
-#endif
-#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
- unsigned int fallback : 1; /*!< is this a fallback? */
-#endif
-#if defined(MBEDTLS_SSL_SRV_C)
- unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in
- Certificate Request messages? */
-#endif
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ /*! ordered list of supported srtp profile */
+ const mbedtls_ssl_srtp_profile *dtls_srtp_profile_list;
+ /*! number of supported profiles */
+ size_t dtls_srtp_profile_list_len;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
};
-
struct mbedtls_ssl_context
{
const mbedtls_ssl_config *conf; /*!< configuration information */
@@ -1127,6 +1289,12 @@ struct mbedtls_ssl_context
unsigned badmac_seen; /*!< records with a bad MAC received */
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ /** Callback to customize X.509 certificate chain verification */
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+ void *p_vrfy; /*!< context for X.509 verify callback */
+#endif
+
mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
mbedtls_ssl_recv_timeout_t *f_recv_timeout;
@@ -1169,6 +1337,10 @@ struct mbedtls_ssl_context
TLS: maintained by us
DTLS: read from peer */
unsigned char *in_hdr; /*!< start of record header */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ unsigned char *in_cid; /*!< The start of the CID;
+ * (the end is marked by in_len). */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
unsigned char *in_len; /*!< two-bytes message length field */
unsigned char *in_iv; /*!< ivlen-byte IV */
unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */
@@ -1177,6 +1349,9 @@ struct mbedtls_ssl_context
int in_msgtype; /*!< record header: message type */
size_t in_msglen; /*!< record header: message length */
size_t in_left; /*!< amount of data read so far */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len; /*!< length of input buffer */
+#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
uint16_t in_epoch; /*!< DTLS epoch for incoming records */
size_t next_record_offset; /*!< offset of the next record in datagram
@@ -1205,6 +1380,10 @@ struct mbedtls_ssl_context
unsigned char *out_buf; /*!< output buffer */
unsigned char *out_ctr; /*!< 64-bit outgoing message counter */
unsigned char *out_hdr; /*!< start of record header */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ unsigned char *out_cid; /*!< The start of the CID;
+ * (the end is marked by in_len). */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
unsigned char *out_len; /*!< two-bytes message length field */
unsigned char *out_iv; /*!< ivlen-byte IV */
unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */
@@ -1212,6 +1391,9 @@ struct mbedtls_ssl_context
int out_msgtype; /*!< record header: message type */
size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len; /*!< length of output buffer */
+#endif
unsigned char cur_out_ctr[8]; /*!< Outgoing record sequence number. */
@@ -1243,6 +1425,13 @@ struct mbedtls_ssl_context
const char *alpn_chosen; /*!< negotiated protocol */
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ /*
+ * use_srtp extension
+ */
+ mbedtls_dtls_srtp_info dtls_srtp_info;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Information for DTLS hello verify
*/
@@ -1262,25 +1451,59 @@ struct mbedtls_ssl_context
char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */
#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* CID configuration to use in subsequent handshakes. */
+
+ /*! The next incoming CID, chosen by the user and applying to
+ * all subsequent handshakes. This may be different from the
+ * CID currently used in case the user has re-configured the CID
+ * after an initial handshake. */
+ unsigned char own_cid[ MBEDTLS_SSL_CID_IN_LEN_MAX ];
+ uint8_t own_cid_len; /*!< The length of \c own_cid. */
+ uint8_t negotiate_cid; /*!< This indicates whether the CID extension should
+ * be negotiated in the next handshake or not.
+ * Possible values are #MBEDTLS_SSL_CID_ENABLED
+ * and #MBEDTLS_SSL_CID_DISABLED. */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
};
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
-#define MBEDTLS_SSL_CHANNEL_OUTBOUND 0
-#define MBEDTLS_SSL_CHANNEL_INBOUND 1
-
-extern int (*mbedtls_ssl_hw_record_init)(mbedtls_ssl_context *ssl,
- const unsigned char *key_enc, const unsigned char *key_dec,
- size_t keylen,
- const unsigned char *iv_enc, const unsigned char *iv_dec,
- size_t ivlen,
- const unsigned char *mac_enc, const unsigned char *mac_dec,
- size_t maclen);
-extern int (*mbedtls_ssl_hw_record_activate)(mbedtls_ssl_context *ssl, int direction);
-extern int (*mbedtls_ssl_hw_record_reset)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_write)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_read)(mbedtls_ssl_context *ssl);
-extern int (*mbedtls_ssl_hw_record_finish)(mbedtls_ssl_context *ssl);
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#define MBEDTLS_SSL_CHANNEL_OUTBOUND MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 0 )
+#define MBEDTLS_SSL_CHANNEL_INBOUND MBEDTLS_DEPRECATED_NUMERIC_CONSTANT( 1 )
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif /* MBEDTLS_DEPRECATED_WARNING */
+
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_init)(
+ mbedtls_ssl_context *ssl,
+ const unsigned char *key_enc, const unsigned char *key_dec,
+ size_t keylen,
+ const unsigned char *iv_enc, const unsigned char *iv_dec,
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen);
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_activate)(
+ mbedtls_ssl_context *ssl,
+ int direction );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_reset)(
+ mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_write)(
+ mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_read)(
+ mbedtls_ssl_context *ssl );
+MBEDTLS_DEPRECATED extern int (*mbedtls_ssl_hw_record_finish)(
+ mbedtls_ssl_context *ssl );
+
+#undef MBEDTLS_DEPRECATED
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
+
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
/**
@@ -1403,13 +1626,17 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
/**
* \brief Set the verification callback (Optional).
*
- * If set, the verify callback is called for each
- * certificate in the chain. For implementation
- * information, please see \c mbedtls_x509_crt_verify()
+ * If set, the provided verify callback is called for each
+ * certificate in the peer's CRT chain, including the trusted
+ * root. For more information, please see the documentation of
+ * \c mbedtls_x509_crt_verify().
*
- * \param conf SSL configuration
- * \param f_vrfy verification function
- * \param p_vrfy verification parameter
+ * \note For per context callbacks and contexts, please use
+ * mbedtls_ssl_set_verify() instead.
+ *
+ * \param conf The SSL configuration to use.
+ * \param f_vrfy The verification callback to use during CRT verification.
+ * \param p_vrfy The opaque context to be passed to the callback.
*/
void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
@@ -1482,6 +1709,142 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
mbedtls_ssl_recv_timeout_t *f_recv_timeout );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+
+
+/**
+ * \brief Configure the use of the Connection ID (CID)
+ * extension in the next handshake.
+ *
+ * Reference: draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * The DTLS CID extension allows the reliable association of
+ * DTLS records to DTLS connections across changes in the
+ * underlying transport (changed IP and Port metadata) by
+ * adding explicit connection identifiers (CIDs) to the
+ * headers of encrypted DTLS records. The desired CIDs are
+ * configured by the application layer and are exchanged in
+ * new `ClientHello` / `ServerHello` extensions during the
+ * handshake, where each side indicates the CID it wants the
+ * peer to use when writing encrypted messages. The CIDs are
+ * put to use once records get encrypted: the stack discards
+ * any incoming records that don't include the configured CID
+ * in their header, and adds the peer's requested CID to the
+ * headers of outgoing messages.
+ *
+ * This API enables or disables the use of the CID extension
+ * in the next handshake and sets the value of the CID to
+ * be used for incoming messages.
+ *
+ * \param ssl The SSL context to configure. This must be initialized.
+ * \param enable This value determines whether the CID extension should
+ * be used or not. Possible values are:
+ * - MBEDTLS_SSL_CID_ENABLED to enable the use of the CID.
+ * - MBEDTLS_SSL_CID_DISABLED (default) to disable the use
+ * of the CID.
+ * \param own_cid The address of the readable buffer holding the CID we want
+ * the peer to use when sending encrypted messages to us.
+ * This may be \c NULL if \p own_cid_len is \c 0.
+ * This parameter is unused if \p enabled is set to
+ * MBEDTLS_SSL_CID_DISABLED.
+ * \param own_cid_len The length of \p own_cid.
+ * This parameter is unused if \p enabled is set to
+ * MBEDTLS_SSL_CID_DISABLED.
+ *
+ * \note The value of \p own_cid_len must match the value of the
+ * \c len parameter passed to mbedtls_ssl_conf_cid()
+ * when configuring the ::mbedtls_ssl_config that \p ssl
+ * is bound to.
+ *
+ * \note This CID configuration applies to subsequent handshakes
+ * performed on the SSL context \p ssl, but does not trigger
+ * one. You still have to call `mbedtls_ssl_handshake()`
+ * (for the initial handshake) or `mbedtls_ssl_renegotiate()`
+ * (for a renegotiation handshake) explicitly after a
+ * successful call to this function to run the handshake.
+ *
+ * \note This call cannot guarantee that the use of the CID
+ * will be successfully negotiated in the next handshake,
+ * because the peer might not support it. Specifically:
+ * - On the Client, enabling the use of the CID through
+ * this call implies that the `ClientHello` in the next
+ * handshake will include the CID extension, thereby
+ * offering the use of the CID to the server. Only if
+ * the `ServerHello` contains the CID extension, too,
+ * the CID extension will actually be put to use.
+ * - On the Server, enabling the use of the CID through
+ * this call implies that that the server will look for
+ * the CID extension in a `ClientHello` from the client,
+ * and, if present, reply with a CID extension in its
+ * `ServerHello`.
+ *
+ * \note To check whether the use of the CID was negotiated
+ * after the subsequent handshake has completed, please
+ * use the API mbedtls_ssl_get_peer_cid().
+ *
+ * \warning If the use of the CID extension is enabled in this call
+ * and the subsequent handshake negotiates its use, Mbed TLS
+ * will silently drop every packet whose CID does not match
+ * the CID configured in \p own_cid. It is the responsibility
+ * of the user to adapt the underlying transport to take care
+ * of CID-based demultiplexing before handing datagrams to
+ * Mbed TLS.
+ *
+ * \return \c 0 on success. In this case, the CID configuration
+ * applies to the next handshake.
+ * \return A negative error code on failure.
+ */
+int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl,
+ int enable,
+ unsigned char const *own_cid,
+ size_t own_cid_len );
+
+/**
+ * \brief Get information about the use of the CID extension
+ * in the current connection.
+ *
+ * \param ssl The SSL context to query.
+ * \param enabled The address at which to store whether the CID extension
+ * is currently in use or not. If the CID is in use,
+ * `*enabled` is set to MBEDTLS_SSL_CID_ENABLED;
+ * otherwise, it is set to MBEDTLS_SSL_CID_DISABLED.
+ * \param peer_cid The address of the buffer in which to store the CID
+ * chosen by the peer (if the CID extension is used).
+ * This may be \c NULL in case the value of peer CID
+ * isn't needed. If it is not \c NULL, \p peer_cid_len
+ * must not be \c NULL.
+ * \param peer_cid_len The address at which to store the size of the CID
+ * chosen by the peer (if the CID extension is used).
+ * This is also the number of Bytes in \p peer_cid that
+ * have been written.
+ * This may be \c NULL in case the length of the peer CID
+ * isn't needed. If it is \c NULL, \p peer_cid must be
+ * \c NULL, too.
+ *
+ * \note This applies to the state of the CID negotiated in
+ * the last complete handshake. If a handshake is in
+ * progress, this function will attempt to complete
+ * the handshake first.
+ *
+ * \note If CID extensions have been exchanged but both client
+ * and server chose to use an empty CID, this function
+ * sets `*enabled` to #MBEDTLS_SSL_CID_DISABLED
+ * (the rationale for this is that the resulting
+ * communication is the same as if the CID extensions
+ * hadn't been used).
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
+ int *enabled,
+ unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ],
+ size_t *peer_cid_len );
+
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
/**
* \brief Set the Maximum Tranport Unit (MTU).
* Special value: 0 means unset (no limit).
@@ -1527,6 +1890,30 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+/**
+ * \brief Set a connection-specific verification callback (optional).
+ *
+ * If set, the provided verify callback is called for each
+ * certificate in the peer's CRT chain, including the trusted
+ * root. For more information, please see the documentation of
+ * \c mbedtls_x509_crt_verify().
+ *
+ * \note This call is analogous to mbedtls_ssl_conf_verify() but
+ * binds the verification callback and context to an SSL context
+ * as opposed to an SSL configuration.
+ * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify()
+ * are both used, mbedtls_ssl_set_verify() takes precedence.
+ *
+ * \param ssl The SSL context to use.
+ * \param f_vrfy The verification callback to use during CRT verification.
+ * \param p_vrfy The opaque context to be passed to the callback.
+ */
+void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy );
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
/**
* \brief Set the timeout period for mbedtls_ssl_read()
* (Default: no timeout.)
@@ -1545,6 +1932,56 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu );
*/
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+/**
+ * \brief Check whether a buffer contains a valid and authentic record
+ * that has not been seen before. (DTLS only).
+ *
+ * This function does not change the user-visible state
+ * of the SSL context. Its sole purpose is to provide
+ * an indication of the legitimacy of an incoming record.
+ *
+ * This can be useful e.g. in distributed server environments
+ * using the DTLS Connection ID feature, in which connections
+ * might need to be passed between service instances on a change
+ * of peer address, but where such disruptive operations should
+ * only happen after the validity of incoming records has been
+ * confirmed.
+ *
+ * \param ssl The SSL context to use.
+ * \param buf The address of the buffer holding the record to be checked.
+ * This must be a read/write buffer of length \p buflen Bytes.
+ * \param buflen The length of \p buf in Bytes.
+ *
+ * \note This routine only checks whether the provided buffer begins
+ * with a valid and authentic record that has not been seen
+ * before, but does not check potential data following the
+ * initial record. In particular, it is possible to pass DTLS
+ * datagrams containing multiple records, in which case only
+ * the first record is checked.
+ *
+ * \note This function modifies the input buffer \p buf. If you need
+ * to preserve the original record, you have to maintain a copy.
+ *
+ * \return \c 0 if the record is valid and authentic and has not been
+ * seen before.
+ * \return MBEDTLS_ERR_SSL_INVALID_MAC if the check completed
+ * successfully but the record was found to be not authentic.
+ * \return MBEDTLS_ERR_SSL_INVALID_RECORD if the check completed
+ * successfully but the record was found to be invalid for
+ * a reason different from authenticity checking.
+ * \return MBEDTLS_ERR_SSL_UNEXPECTED_RECORD if the check completed
+ * successfully but the record was found to be unexpected
+ * in the state of the SSL context, including replayed records.
+ * \return Another negative error code on different kinds of failure.
+ * In this case, the SSL context becomes unusable and needs
+ * to be freed or reset before reuse.
+ */
+int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t buflen );
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+
/**
* \brief Set the timer callbacks (Mandatory for DTLS.)
*
@@ -1623,6 +2060,41 @@ typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
size_t maclen,
size_t keylen,
size_t ivlen );
+
+/**
+ * \brief Callback type: Export key block, master secret,
+ * handshake randbytes and the tls_prf function
+ * used to derive keys.
+ *
+ * \note This is required for certain uses of TLS, e.g. EAP-TLS
+ * (RFC 5216) and Thread. The key pointers are ephemeral and
+ * therefore must not be stored. The master secret and keys
+ * should not be used directly except as an input to a key
+ * derivation function.
+ *
+ * \param p_expkey Context for the callback.
+ * \param ms Pointer to master secret (fixed length: 48 bytes).
+ * \param kb Pointer to key block, see RFC 5246 section 6.3.
+ * (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
+ * \param maclen MAC length.
+ * \param keylen Key length.
+ * \param ivlen IV length.
+ * \param client_random The client random bytes.
+ * \param server_random The server random bytes.
+ * \param tls_prf_type The tls_prf enum type.
+ *
+ * \return 0 if successful, or
+ * a specific MBEDTLS_ERR_XXX code.
+ */
+typedef int mbedtls_ssl_export_keys_ext_t( void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen,
+ const unsigned char client_random[32],
+ const unsigned char server_random[32],
+ mbedtls_tls_prf_types tls_prf_type );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/**
@@ -1688,6 +2160,22 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys );
+
+/**
+ * \brief Configure extended key export callback.
+ * (Default: none.)
+ *
+ * \note See \c mbedtls_ssl_export_keys_ext_t.
+ * \warning Exported key material must not be used for any purpose
+ * before the (D)TLS handshake is completed
+ *
+ * \param conf SSL configuration context
+ * \param f_export_keys_ext Callback for exporting keys
+ * \param p_export_keys Context for the callback
+ */
+void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
+ void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -2039,6 +2527,90 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
#endif /* MBEDTLS_SSL_CLI_C */
/**
+ * \brief Load serialized session data into a session structure.
+ * On client, this can be used for loading saved sessions
+ * before resuming them with mbedstls_ssl_set_session().
+ * On server, this can be used for alternative implementations
+ * of session cache or session tickets.
+ *
+ * \warning If a peer certificate chain is associated with the session,
+ * the serialized state will only contain the peer's
+ * end-entity certificate and the result of the chain
+ * verification (unless verification was disabled), but not
+ * the rest of the chain.
+ *
+ * \see mbedtls_ssl_session_save()
+ * \see mbedtls_ssl_set_session()
+ *
+ * \param session The session structure to be populated. It must have been
+ * initialised with mbedtls_ssl_session_init() but not
+ * populated yet.
+ * \param buf The buffer holding the serialized session data. It must be a
+ * readable buffer of at least \p len bytes.
+ * \param len The size of the serialized data in bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
+ * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
+ * was generated in a different version or configuration of
+ * Mbed TLS.
+ * \return Another negative value for other kinds of errors (for
+ * example, unsupported features in the embedded certificate).
+ */
+int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len );
+
+/**
+ * \brief Save session structure as serialized data in a buffer.
+ * On client, this can be used for saving session data,
+ * potentially in non-volatile storage, for resuming later.
+ * On server, this can be used for alternative implementations
+ * of session cache or session tickets.
+ *
+ * \see mbedtls_ssl_session_load()
+ * \see mbedtls_ssl_get_session_pointer()
+ *
+ * \param session The session structure to be saved.
+ * \param buf The buffer to write the serialized data to. It must be a
+ * writeable buffer of at least \p len bytes, or may be \c
+ * NULL if \p len is \c 0.
+ * \param buf_len The number of bytes available for writing in \p buf.
+ * \param olen The size in bytes of the data that has been or would have
+ * been written. It must point to a valid \c size_t.
+ *
+ * \note \p olen is updated to the correct value regardless of
+ * whether \p buf_len was large enough. This makes it possible
+ * to determine the necessary size by calling this function
+ * with \p buf set to \c NULL and \p buf_len to \c 0.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
+ */
+int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen );
+
+/**
+ * \brief Get a pointer to the current session structure, for example
+ * to serialize it.
+ *
+ * \warning Ownership of the session remains with the SSL context, and
+ * the returned pointer is only guaranteed to be valid until
+ * the next API call operating on the same \p ssl context.
+ *
+ * \see mbedtls_ssl_session_save()
+ *
+ * \param ssl The SSL context.
+ *
+ * \return A pointer to the current session if successful.
+ * \return \c NULL if no session is active.
+ */
+const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl );
+
+/**
* \brief Set the list of allowed ciphersuites and the preference
* order. First in the list has the highest preference.
* (Overrides all version-specific lists)
@@ -2056,6 +2628,45 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf,
const int *ciphersuites );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0
+#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1
+/**
+ * \brief Specify the length of Connection IDs for incoming
+ * encrypted DTLS records, as well as the behaviour
+ * on unexpected CIDs.
+ *
+ * By default, the CID length is set to \c 0,
+ * and unexpected CIDs are silently ignored.
+ *
+ * \param conf The SSL configuration to modify.
+ * \param len The length in Bytes of the CID fields in encrypted
+ * DTLS records using the CID mechanism. This must
+ * not be larger than #MBEDTLS_SSL_CID_OUT_LEN_MAX.
+ * \param ignore_other_cids This determines the stack's behaviour when
+ * receiving a record with an unexpected CID.
+ * Possible values are:
+ * - #MBEDTLS_SSL_UNEXPECTED_CID_IGNORE
+ * In this case, the record is silently ignored.
+ * - #MBEDTLS_SSL_UNEXPECTED_CID_FAIL
+ * In this case, the stack fails with the specific
+ * error code #MBEDTLS_ERR_SSL_UNEXPECTED_CID.
+ *
+ * \note The CID specification allows implementations to either
+ * use a common length for all incoming connection IDs or
+ * allow variable-length incoming IDs. Mbed TLS currently
+ * requires a common length for all connections sharing the
+ * same SSL configuration; this allows simpler parsing of
+ * record headers.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len
+ * is too large.
+ */
+int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len,
+ int ignore_other_cids );
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
/**
* \brief Set the list of allowed ciphersuites and the
* preference order for a specific version of the protocol.
@@ -2108,6 +2719,63 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
mbedtls_x509_crt *ca_chain,
mbedtls_x509_crl *ca_crl );
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/**
+ * \brief Set the trusted certificate callback.
+ *
+ * This API allows to register the set of trusted certificates
+ * through a callback, instead of a linked list as configured
+ * by mbedtls_ssl_conf_ca_chain().
+ *
+ * This is useful for example in contexts where a large number
+ * of CAs are used, and the inefficiency of maintaining them
+ * in a linked list cannot be tolerated. It is also useful when
+ * the set of trusted CAs needs to be modified frequently.
+ *
+ * See the documentation of `mbedtls_x509_crt_ca_cb_t` for
+ * more information.
+ *
+ * \param conf The SSL configuration to register the callback with.
+ * \param f_ca_cb The trusted certificate callback to use when verifying
+ * certificate chains.
+ * \param p_ca_cb The context to be passed to \p f_ca_cb (for example,
+ * a reference to a trusted CA database).
+ *
+ * \note This API is incompatible with mbedtls_ssl_conf_ca_chain():
+ * Any call to this function overwrites the values set through
+ * earlier calls to mbedtls_ssl_conf_ca_chain() or
+ * mbedtls_ssl_conf_ca_cb().
+ *
+ * \note This API is incompatible with CA indication in
+ * CertificateRequest messages: A server-side SSL context which
+ * is bound to an SSL configuration that uses a CA callback
+ * configured via mbedtls_ssl_conf_ca_cb(), and which requires
+ * client authentication, will send an empty CA list in the
+ * corresponding CertificateRequest message.
+ *
+ * \note This API is incompatible with mbedtls_ssl_set_hs_ca_chain():
+ * If an SSL context is bound to an SSL configuration which uses
+ * CA callbacks configured via mbedtls_ssl_conf_ca_cb(), then
+ * calls to mbedtls_ssl_set_hs_ca_chain() have no effect.
+ *
+ * \note The use of this API disables the use of restartable ECC
+ * during X.509 CRT signature verification (but doesn't affect
+ * other uses).
+ *
+ * \warning This API is incompatible with the use of CRLs. Any call to
+ * mbedtls_ssl_conf_ca_cb() unsets CRLs configured through
+ * earlier calls to mbedtls_ssl_conf_ca_chain().
+ *
+ * \warning In multi-threaded environments, the callback \p f_ca_cb
+ * must be thread-safe, and it is the user's responsibility
+ * to guarantee this (for example through a mutex
+ * contained in the callback context pointed to by \p p_ca_cb).
+ */
+void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb );
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
/**
* \brief Set own certificate chain and private key
*
@@ -2149,76 +2817,172 @@ int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
mbedtls_pk_context *pk_key );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
/**
- * \brief Set the Pre Shared Key (PSK) and the expected identity name
+ * \brief Configure a pre-shared key (PSK) and identity
+ * to be used in PSK-based ciphersuites.
*
* \note This is mainly useful for clients. Servers will usually
* want to use \c mbedtls_ssl_conf_psk_cb() instead.
*
- * \note Currently clients can only register one pre-shared key.
- * In other words, the servers' identity hint is ignored.
+ * \note A PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback
+ * takes precedence over a PSK configured by this function.
+ *
+ * \warning Currently, clients can only register a single pre-shared key.
+ * Calling this function or mbedtls_ssl_conf_psk_opaque() more
+ * than once will overwrite values configured in previous calls.
* Support for setting multiple PSKs on clients and selecting
- * one based on the identity hint is not a planned feature but
- * feedback is welcomed.
+ * one based on the identity hint is not a planned feature,
+ * but feedback is welcomed.
*
- * \param conf SSL configuration
- * \param psk pointer to the pre-shared key
- * \param psk_len pre-shared key length
- * \param psk_identity pointer to the pre-shared key identity
- * \param psk_identity_len identity key length
+ * \param conf The SSL configuration to register the PSK with.
+ * \param psk The pointer to the pre-shared key to use.
+ * \param psk_len The length of the pre-shared key in bytes.
+ * \param psk_identity The pointer to the pre-shared key identity.
+ * \param psk_identity_len The length of the pre-shared key identity
+ * in bytes.
+ *
+ * \note The PSK and its identity are copied internally and
+ * hence need not be preserved by the caller for the lifetime
+ * of the SSL configuration.
*
- * \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Configure an opaque pre-shared key (PSK) and identity
+ * to be used in PSK-based ciphersuites.
+ *
+ * \note This is mainly useful for clients. Servers will usually
+ * want to use \c mbedtls_ssl_conf_psk_cb() instead.
+ *
+ * \note An opaque PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in
+ * the PSK callback takes precedence over an opaque PSK
+ * configured by this function.
+ *
+ * \warning Currently, clients can only register a single pre-shared key.
+ * Calling this function or mbedtls_ssl_conf_psk() more than
+ * once will overwrite values configured in previous calls.
+ * Support for setting multiple PSKs on clients and selecting
+ * one based on the identity hint is not a planned feature,
+ * but feedback is welcomed.
+ *
+ * \param conf The SSL configuration to register the PSK with.
+ * \param psk The identifier of the key slot holding the PSK.
+ * Until \p conf is destroyed or this function is successfully
+ * called again, the key slot \p psk must be populated with a
+ * key of type PSA_ALG_CATEGORY_KEY_DERIVATION whose policy
+ * allows its use for the key derivation algorithm applied
+ * in the handshake.
+ * \param psk_identity The pointer to the pre-shared key identity.
+ * \param psk_identity_len The length of the pre-shared key identity
+ * in bytes.
+ *
+ * \note The PSK identity hint is copied internally and hence need
+ * not be preserved by the caller for the lifetime of the
+ * SSL configuration.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
+ psa_key_id_t psk,
+ const unsigned char *psk_identity,
+ size_t psk_identity_len );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/**
- * \brief Set the Pre Shared Key (PSK) for the current handshake
+ * \brief Set the pre-shared Key (PSK) for the current handshake.
*
* \note This should only be called inside the PSK callback,
- * ie the function passed to \c mbedtls_ssl_conf_psk_cb().
+ * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
*
- * \param ssl SSL context
- * \param psk pointer to the pre-shared key
- * \param psk_len pre-shared key length
+ * \note A PSK set by this function takes precedence over a PSK
+ * configured by \c mbedtls_ssl_conf_psk().
*
- * \return 0 if successful or MBEDTLS_ERR_SSL_ALLOC_FAILED
+ * \param ssl The SSL context to configure a PSK for.
+ * \param psk The pointer to the pre-shared key.
+ * \param psk_len The length of the pre-shared key in bytes.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
*/
int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
const unsigned char *psk, size_t psk_len );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * \brief Set an opaque pre-shared Key (PSK) for the current handshake.
+ *
+ * \note This should only be called inside the PSK callback,
+ * i.e. the function passed to \c mbedtls_ssl_conf_psk_cb().
+ *
+ * \note An opaque PSK set by this function takes precedence over an
+ * opaque PSK configured by \c mbedtls_ssl_conf_psk_opaque().
+ *
+ * \param ssl The SSL context to configure a PSK for.
+ * \param psk The identifier of the key slot holding the PSK.
+ * For the duration of the current handshake, the key slot
+ * must be populated with a key of type
+ * PSA_ALG_CATEGORY_KEY_DERIVATION whose policy allows its
+ * use for the key derivation algorithm
+ * applied in the handshake.
+ *
+ * \return \c 0 if successful.
+ * \return An \c MBEDTLS_ERR_SSL_XXX error code on failure.
+ */
+int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
+ psa_key_id_t psk );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/**
* \brief Set the PSK callback (server-side only).
*
* If set, the PSK callback is called for each
- * handshake where a PSK ciphersuite was negotiated.
+ * handshake where a PSK-based ciphersuite was negotiated.
* The caller provides the identity received and wants to
* receive the actual PSK data and length.
*
- * The callback has the following parameters: (void *parameter,
- * mbedtls_ssl_context *ssl, const unsigned char *psk_identity,
- * size_t identity_len)
+ * The callback has the following parameters:
+ * - \c void*: The opaque pointer \p p_psk.
+ * - \c mbedtls_ssl_context*: The SSL context to which
+ * the operation applies.
+ * - \c const unsigned char*: The PSK identity
+ * selected by the client.
+ * - \c size_t: The length of the PSK identity
+ * selected by the client.
+ *
* If a valid PSK identity is found, the callback should use
- * \c mbedtls_ssl_set_hs_psk() on the ssl context to set the
- * correct PSK and return 0.
+ * \c mbedtls_ssl_set_hs_psk() or
+ * \c mbedtls_ssl_set_hs_psk_opaque()
+ * on the SSL context to set the correct PSK and return \c 0.
* Any other return value will result in a denied PSK identity.
*
- * \note If you set a PSK callback using this function, then you
- * don't need to set a PSK key and identity using
- * \c mbedtls_ssl_conf_psk().
- *
- * \param conf SSL configuration
- * \param f_psk PSK identity function
- * \param p_psk PSK identity parameter
+ * \note A dynamic PSK (i.e. set by the PSK callback) takes
+ * precedence over a static PSK (i.e. set by
+ * \c mbedtls_ssl_conf_psk() or
+ * \c mbedtls_ssl_conf_psk_opaque()).
+ * This means that if you set a PSK callback using this
+ * function, you don't need to set a PSK using
+ * \c mbedtls_ssl_conf_psk() or
+ * \c mbedtls_ssl_conf_psk_opaque()).
+ *
+ * \param conf The SSL configuration to register the callback with.
+ * \param f_psk The callback for selecting and setting the PSK based
+ * in the PSK identity chosen by the client.
+ * \param p_psk A pointer to an opaque structure to be passed to
+ * the callback, for example a PSK store.
*/
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
size_t),
void *p_psk );
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
@@ -2294,7 +3058,9 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_ECP_C)
/**
* \brief Set the allowed curves in order of preference.
- * (Default: all defined curves in order of decreasing size.)
+ * (Default: all defined curves in order of decreasing size,
+ * except that Montgomery curves come last. This order
+ * is likely to change in a future version.)
*
* On server: this only affects selection of the ECDHE curve;
* the curves used for ECDH and ECDSA are determined by the
@@ -2323,7 +3089,7 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
const mbedtls_ecp_group_id *curves );
#endif /* MBEDTLS_ECP_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/**
* \brief Set the allowed hashes for signatures during the handshake.
* (Default: all SHA-2 hashes, largest first. Also SHA-1 if
@@ -2346,7 +3112,7 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
*/
void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
const int *hashes );
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
@@ -2494,6 +3260,105 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot
const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+#if defined(MBEDTLS_DEBUG_C)
+static inline const char *mbedtls_ssl_get_srtp_profile_as_string( mbedtls_ssl_srtp_profile profile )
+{
+ switch( profile )
+ {
+ case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
+ return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80" );
+ case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
+ return( "MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32" );
+ case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
+ return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80" );
+ case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
+ return( "MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32" );
+ default: break;
+ }
+ return( "" );
+}
+#endif /* MBEDTLS_DEBUG_C */
+/**
+ * \brief Manage support for mki(master key id) value
+ * in use_srtp extension.
+ * MKI is an optional part of SRTP used for key management
+ * and re-keying. See RFC3711 section 3.1 for details.
+ * The default value is
+ * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED.
+ *
+ * \param conf The SSL configuration to manage mki support.
+ * \param support_mki_value Enable or disable mki usage. Values are
+ * #MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED
+ * or #MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED.
+ */
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+ int support_mki_value );
+
+/**
+ * \brief Set the supported DTLS-SRTP protection profiles.
+ *
+ * \param conf SSL configuration
+ * \param profiles Pointer to a List of MBEDTLS_TLS_SRTP_UNSET terminated
+ * supported protection profiles
+ * in decreasing preference order.
+ * The pointer to the list is recorded by the library
+ * for later reference as required, so the lifetime
+ * of the table must be at least as long as the lifetime
+ * of the SSL configuration structure.
+ * The list must not hold more than
+ * MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH elements
+ * (excluding the terminating MBEDTLS_TLS_SRTP_UNSET).
+ *
+ * \return 0 on success
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA when the list of
+ * protection profiles is incorrect.
+ */
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles
+ ( mbedtls_ssl_config *conf,
+ const mbedtls_ssl_srtp_profile *profiles );
+
+/**
+ * \brief Set the mki_value for the current DTLS-SRTP session.
+ *
+ * \param ssl SSL context to use.
+ * \param mki_value The MKI value to set.
+ * \param mki_len The length of the MKI value.
+ *
+ * \note This function is relevant on client side only.
+ * The server discovers the mki value during handshake.
+ * A mki value set on server side using this function
+ * is ignored.
+ *
+ * \return 0 on success
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA
+ * \return #MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE
+ */
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+ unsigned char *mki_value,
+ uint16_t mki_len );
+/**
+ * \brief Get the negotiated DTLS-SRTP informations:
+ * Protection profile and MKI value.
+ *
+ * \warning This function must be called after the handshake is
+ * completed. The value returned by this function must
+ * not be trusted or acted upon before the handshake completes.
+ *
+ * \param ssl The SSL context to query.
+ * \param dtls_srtp_info The negotiated DTLS-SRTP informations:
+ * - Protection profile in use.
+ * A direct mapping of the iana defined value for protection
+ * profile on an uint16_t.
+ http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ * #MBEDTLS_TLS_SRTP_UNSET if the use of SRTP was not negotiated
+ * or peer's Hello packet was not parsed yet.
+ * - mki size and value( if size is > 0 ).
+ */
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+ mbedtls_dtls_srtp_info *dtls_srtp_info );
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/**
* \brief Set the maximum supported version sent from the client side
* and/or accepted at the server side
@@ -2593,7 +3458,7 @@ void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems
* \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
* for security reasons. Use at your own risk.
*
- * \note This function is deprecated and will likely be removed in
+ * \note This function is deprecated and will be removed in
* a future version of the library.
* RC4 is disabled by default at compile time and needs to be
* actively enabled for use with legacy systems.
@@ -2634,14 +3499,14 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf,
* been set via this function to a value different than
* #MBEDTLS_SSL_MAX_FRAG_LEN_NONE.
*
- * \note This sets the maximum length for a record's payload,
- * excluding record overhead that will be added to it, see
- * \c mbedtls_ssl_get_record_expansion().
- *
* \note With TLS, this currently only affects ApplicationData (sent
* with \c mbedtls_ssl_read()), not handshake messages.
* With DTLS, this affects both ApplicationData and handshake.
*
+ * \note This sets the maximum length for a record's payload,
+ * excluding record overhead that will be added to it, see
+ * \c mbedtls_ssl_get_record_expansion().
+ *
* \note For DTLS, it is also possible to set a limit for the total
* size of daragrams passed to the transport layer, including
* record overhead, see \c mbedtls_ssl_set_mtu().
@@ -2792,7 +3657,7 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_
* (Default: 2^48 - 1)
*
* Renegotiation is automatically triggered when a record
- * counter (outgoing or ingoing) crosses the defined
+ * counter (outgoing or incoming) crosses the defined
* threshold. The default value is meant to prevent the
* connection from being closed when the counter is about to
* reached its maximal value (it is not allowed to wrap).
@@ -2922,18 +3787,61 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
- * \brief Return the maximum fragment length (payload, in bytes).
- * This is the value negotiated with peer if any,
- * or the locally configured value.
+ * \brief Return the maximum fragment length (payload, in bytes) for
+ * the output buffer. For the client, this is the configured
+ * value. For the server, it is the minimum of two - the
+ * configured value and the negotiated one.
+ *
+ * \sa mbedtls_ssl_conf_max_frag_len()
+ * \sa mbedtls_ssl_get_max_record_payload()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum fragment length for the output buffer.
+ */
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the maximum fragment length (payload, in bytes) for
+ * the input buffer. This is the negotiated maximum fragment
+ * length, or, if there is none, MBEDTLS_SSL_MAX_CONTENT_LEN.
+ * If it is not defined either, the value is 2^14. This function
+ * works as its predecessor, \c mbedtls_ssl_get_max_frag_len().
*
* \sa mbedtls_ssl_conf_max_frag_len()
* \sa mbedtls_ssl_get_max_record_payload()
*
* \param ssl SSL context
*
- * \return Current maximum fragment length.
+ * \return Current maximum fragment length for the output buffer.
*/
-size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief This function is a deprecated approach to getting the max
+ * fragment length. Its an alias for
+ * \c mbedtls_ssl_get_output_max_frag_len(), as the behaviour
+ * is the same. See \c mbedtls_ssl_get_output_max_frag_len() for
+ * more detail.
+ *
+ * \sa mbedtls_ssl_get_input_max_frag_len()
+ * \sa mbedtls_ssl_get_output_max_frag_len()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum fragment length for the output buffer.
+ */
+MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len(
+ const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
/**
@@ -2954,7 +3862,8 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
* when record compression is enabled.
*
* \sa mbedtls_ssl_set_mtu()
- * \sa mbedtls_ssl_get_max_frag_len()
+ * \sa mbedtls_ssl_get_output_max_frag_len()
+ * \sa mbedtls_ssl_get_input_max_frag_len()
* \sa mbedtls_ssl_get_record_expansion()
*
* \param ssl SSL context
@@ -2966,18 +3875,34 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
- * \brief Return the peer certificate from the current connection
- *
- * Note: Can be NULL in case no certificate was sent during
- * the handshake. Different calls for the same connection can
- * return the same or different pointers for the same
- * certificate and even a different certificate altogether.
- * The peer cert CAN change in a single connection if
- * renegotiation is performed.
- *
- * \param ssl SSL context
- *
- * \return the current peer certificate
+ * \brief Return the peer certificate from the current connection.
+ *
+ * \param ssl The SSL context to use. This must be initialized and setup.
+ *
+ * \return The current peer certificate, if available.
+ * The returned certificate is owned by the SSL context and
+ * is valid only until the next call to the SSL API.
+ * \return \c NULL if no peer certificate is available. This might
+ * be because the chosen ciphersuite doesn't use CRTs
+ * (PSK-based ciphersuites, for example), or because
+ * #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled,
+ * allowing the stack to free the peer's CRT to save memory.
+ *
+ * \note For one-time inspection of the peer's certificate during
+ * the handshake, consider registering an X.509 CRT verification
+ * callback through mbedtls_ssl_conf_verify() instead of calling
+ * this function. Using mbedtls_ssl_conf_verify() also comes at
+ * the benefit of allowing you to influence the verification
+ * process, for example by masking expected and tolerated
+ * verification failures.
+ *
+ * \warning You must not use the pointer returned by this function
+ * after any further call to the SSL API, including
+ * mbedtls_ssl_read() and mbedtls_ssl_write(); this is
+ * because the pointer might change during renegotiation,
+ * which happens transparently to the user.
+ * If you want to use the certificate across API calls,
+ * you must make a copy.
*/
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
@@ -3122,7 +4047,14 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
*
* \return The (positive) number of bytes read if successful.
* \return \c 0 if the read end of the underlying transport was closed
- * - in this case you must stop using the context (see below).
+ * without sending a CloseNotify beforehand, which might happen
+ * because of various reasons (internal error of an underlying
+ * stack, non-conformant peer not sending a CloseNotify and
+ * such) - in this case you must stop using the context
+ * (see below).
+ * \return #MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY if the underlying
+ * transport is still functional, but the peer has
+ * acknowledged to not send anything anymore.
* \return #MBEDTLS_ERR_SSL_WANT_READ or #MBEDTLS_ERR_SSL_WANT_WRITE
* if the handshake is incomplete and waiting for data to
* be available for reading from or writing to the underlying
@@ -3239,8 +4171,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* or negotiated with the peer), then:
* - with TLS, less bytes than requested are written.
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
- * \c mbedtls_ssl_get_max_frag_len() may be used to query the
- * active maximum fragment length.
+ * \c mbedtls_ssl_get_output_max_frag_len() may be used to
+ * query the active maximum fragment length.
*
* \note Attempting to write 0 bytes will result in an empty TLS
* application record being sent.
@@ -3288,6 +4220,130 @@ int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );
*/
void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+/**
+ * \brief Save an active connection as serialized data in a buffer.
+ * This allows the freeing or re-using of the SSL context
+ * while still picking up the connection later in a way that
+ * it entirely transparent to the peer.
+ *
+ * \see mbedtls_ssl_context_load()
+ *
+ * \note This feature is currently only available under certain
+ * conditions, see the documentation of the return value
+ * #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details.
+ *
+ * \note When this function succeeds, it calls
+ * mbedtls_ssl_session_reset() on \p ssl which as a result is
+ * no longer associated with the connection that has been
+ * serialized. This avoids creating copies of the connection
+ * state. You're then free to either re-use the context
+ * structure for a different connection, or call
+ * mbedtls_ssl_free() on it. See the documentation of
+ * mbedtls_ssl_session_reset() for more details.
+ *
+ * \param ssl The SSL context to save. On success, it is no longer
+ * associated with the connection that has been serialized.
+ * \param buf The buffer to write the serialized data to. It must be a
+ * writeable buffer of at least \p buf_len bytes, or may be \c
+ * NULL if \p buf_len is \c 0.
+ * \param buf_len The number of bytes available for writing in \p buf.
+ * \param olen The size in bytes of the data that has been or would have
+ * been written. It must point to a valid \c size_t.
+ *
+ * \note \p olen is updated to the correct value regardless of
+ * whether \p buf_len was large enough. This makes it possible
+ * to determine the necessary size by calling this function
+ * with \p buf set to \c NULL and \p buf_len to \c 0. However,
+ * the value of \p olen is only guaranteed to be correct when
+ * the function returns #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL or
+ * \c 0. If the return value is different, then the value of
+ * \p olen is undefined.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL if \p buf is too small.
+ * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed
+ * while reseting the context.
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if a handshake is in
+ * progress, or there is pending data for reading or sending,
+ * or the connection does not use DTLS 1.2 with an AEAD
+ * ciphersuite, or renegotiation is enabled.
+ */
+int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen );
+
+/**
+ * \brief Load serialized connection data to an SSL context.
+ *
+ * \see mbedtls_ssl_context_save()
+ *
+ * \warning The same serialized data must never be loaded into more
+ * that one context. In order to ensure that, after
+ * successfully loading serialized data to an SSL context, you
+ * should immediately destroy or invalidate all copies of the
+ * serialized data that was loaded. Loading the same data in
+ * more than one context would cause severe security failures
+ * including but not limited to loss of confidentiality.
+ *
+ * \note Before calling this function, the SSL context must be
+ * prepared in one of the two following ways. The first way is
+ * to take a context freshly initialised with
+ * mbedtls_ssl_init() and call mbedtls_ssl_setup() on it with
+ * the same ::mbedtls_ssl_config structure that was used in
+ * the original connection. The second way is to
+ * call mbedtls_ssl_session_reset() on a context that was
+ * previously prepared as above but used in the meantime.
+ * Either way, you must not use the context to perform a
+ * handshake between calling mbedtls_ssl_setup() or
+ * mbedtls_ssl_session_reset() and calling this function. You
+ * may however call other setter functions in that time frame
+ * as indicated in the note below.
+ *
+ * \note Before or after calling this function successfully, you
+ * also need to configure some connection-specific callbacks
+ * and settings before you can use the connection again
+ * (unless they were already set before calling
+ * mbedtls_ssl_session_reset() and the values are suitable for
+ * the present connection). Specifically, you want to call
+ * at least mbedtls_ssl_set_bio() and
+ * mbedtls_ssl_set_timer_cb(). All other SSL setter functions
+ * are not necessary to call, either because they're only used
+ * in handshakes, or because the setting is already saved. You
+ * might choose to call them anyway, for example in order to
+ * share code between the cases of establishing a new
+ * connection and the case of loading an already-established
+ * connection.
+ *
+ * \note If you have new information about the path MTU, you want to
+ * call mbedtls_ssl_set_mtu() after calling this function, as
+ * otherwise this function would overwrite your
+ * newly-configured value with the value that was active when
+ * the context was saved.
+ *
+ * \note When this function returns an error code, it calls
+ * mbedtls_ssl_free() on \p ssl. In this case, you need to
+ * prepare the context with the usual sequence starting with a
+ * call to mbedtls_ssl_init() if you want to use it again.
+ *
+ * \param ssl The SSL context structure to be populated. It must have
+ * been prepared as described in the note above.
+ * \param buf The buffer holding the serialized connection data. It must
+ * be a readable buffer of at least \p len bytes.
+ * \param len The size of the serialized data in bytes.
+ *
+ * \return \c 0 if successful.
+ * \return #MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed.
+ * \return #MBEDTLS_ERR_SSL_VERSION_MISMATCH if the serialized data
+ * comes from a different Mbed TLS version or build.
+ * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if input data is invalid.
+ */
+int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len );
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
+
/**
* \brief Initialize an SSL configuration context
* Just makes the context ready for
@@ -3343,6 +4399,27 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session );
*/
void mbedtls_ssl_session_free( mbedtls_ssl_session *session );
+/**
+ * \brief TLS-PRF function for key derivation.
+ *
+ * \param prf The tls_prf type function type to be used.
+ * \param secret Secret for the key derivation function.
+ * \param slen Length of the secret.
+ * \param label String label for the key derivation function,
+ * terminated with null character.
+ * \param random Random bytes.
+ * \param rlen Length of the random bytes buffer.
+ * \param dstbuf The buffer holding the derived key.
+ * \param dlen Length of the output buffer.
+ *
+ * \return 0 on success. An SSL specific error on failure.
+ */
+int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen );
+
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
index 612d81776e..c6ef2960f4 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,41 +18,20 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_CACHE_H
#define MBEDTLS_SSL_CACHE_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ssl.h"
+#include "mbedtls/ssl.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
/**
@@ -95,7 +68,8 @@ struct mbedtls_ssl_cache_entry
mbedtls_time_t timestamp; /*!< entry timestamp */
#endif
mbedtls_ssl_session session; /*!< entry session */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_x509_buf peer_cert; /*!< entry peer_cert */
#endif
mbedtls_ssl_cache_entry *next; /*!< chain pointer */
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
index ab8e601db7..93c32a5eda 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,40 +18,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_CIPHERSUITES_H
#define MBEDTLS_SSL_CIPHERSUITES_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "pk.h"
-#include "cipher.h"
-#include "md.h"
+#include "mbedtls/pk.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/md.h"
#ifdef __cplusplus
extern "C" {
@@ -337,7 +310,7 @@ typedef enum {
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
+#define MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED
#endif
/* Key exchanges allowing client certificate requests */
@@ -347,28 +320,28 @@ typedef enum {
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED
+#define MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED
#endif
/* Key exchanges involving server signature in ServerKeyExchange */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED
+#define MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED
#endif
/* Key exchanges using ECDH */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED
#endif
/* Key exchanges that don't involve ephemeral keys */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
- defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED
+ defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
+#define MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED
#endif
/* Key exchanges that involve ephemeral keys */
@@ -378,7 +351,7 @@ typedef enum {
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED
+#define MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED
#endif
/* Key exchanges using a PSK */
@@ -386,20 +359,20 @@ typedef enum {
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED
#endif
/* Key exchanges using DHE */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED
#endif
/* Key exchanges using ECDHE */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
+#define MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED
#endif
typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
@@ -442,7 +415,7 @@ mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphers
int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info );
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -459,9 +432,9 @@ static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -477,9 +450,9 @@ static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -492,7 +465,7 @@ static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersui
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info )
{
@@ -511,7 +484,25 @@ static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ci
}
}
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+static inline int mbedtls_ssl_ciphersuite_uses_srv_cert( const mbedtls_ssl_ciphersuite_t *info )
+{
+ switch( info->key_exchange )
+ {
+ case MBEDTLS_KEY_EXCHANGE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
+ case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
+ case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
+ return( 1 );
+
+ default:
+ return( 0 );
+ }
+}
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -524,9 +515,9 @@ static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuit
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED) */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -540,9 +531,9 @@ static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersu
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED) */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -556,7 +547,7 @@ static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_s
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
#ifdef __cplusplus
}
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
index 9c2d5b62a4..0a238708e5 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,41 +18,20 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_COOKIE_H
#define MBEDTLS_SSL_COOKIE_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ssl.h"
+#include "mbedtls/ssl.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
/**
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
index 6ba6c2af09..6913dc0f66 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,60 +18,48 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_INTERNAL_H
#define MBEDTLS_SSL_INTERNAL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "ssl.h"
-#include "cipher.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/cipher.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#endif
#if defined(MBEDTLS_MD5_C)
-#include "md5.h"
+#include "mbedtls/md5.h"
#endif
#if defined(MBEDTLS_SHA1_C)
-#include "sha1.h"
+#include "mbedtls/sha1.h"
#endif
#if defined(MBEDTLS_SHA256_C)
-#include "sha256.h"
+#include "mbedtls/sha256.h"
#endif
#if defined(MBEDTLS_SHA512_C)
-#include "sha512.h"
+#include "mbedtls/sha512.h"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
-#include "ecjpake.h"
+#include "mbedtls/ecjpake.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
@@ -129,7 +111,7 @@
defined(MBEDTLS_SSL_CLI_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-#define MBEDTLS_SSL__ECP_RESTARTABLE
+#define MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED
#endif
#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0
@@ -150,6 +132,18 @@
#define MBEDTLS_SSL_RETRANS_WAITING 2
#define MBEDTLS_SSL_RETRANS_FINISHED 3
+/*
+ * Allow extra bytes for record, authentication and encryption overhead:
+ * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256)
+ * and allow for a maximum of 1024 of compression expansion if
+ * enabled.
+ */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+#define MBEDTLS_SSL_COMPRESSION_ADD 1024
+#else
+#define MBEDTLS_SSL_COMPRESSION_ADD 0
+#endif
+
/* This macro determines whether CBC is supported. */
#if defined(MBEDTLS_CIPHER_MODE_CBC) && \
( defined(MBEDTLS_AES_C) || \
@@ -168,19 +162,12 @@
#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)
- * and allow for a maximum of 1024 of compression expansion if
- * enabled.
- */
-#if defined(MBEDTLS_ZLIB_SUPPORT)
-#define MBEDTLS_SSL_COMPRESSION_ADD 1024
-#else
-#define MBEDTLS_SSL_COMPRESSION_ADD 0
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
+ defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
+#define MBEDTLS_SSL_SOME_MODES_USE_MAC
#endif
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
/* Ciphersuites using HMAC */
#if defined(MBEDTLS_SHA512_C)
#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */
@@ -189,7 +176,7 @@
#else
#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */
#endif
-#else
+#else /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */
#define MBEDTLS_SSL_MAC_ADD 16
#endif
@@ -200,10 +187,17 @@
#define MBEDTLS_SSL_PADDING_ADD 0
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#define MBEDTLS_SSL_MAX_CID_EXPANSION MBEDTLS_SSL_CID_PADDING_GRANULARITY
+#else
+#define MBEDTLS_SSL_MAX_CID_EXPANSION 0
+#endif
+
#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \
MBEDTLS_MAX_IV_LENGTH + \
MBEDTLS_SSL_MAC_ADD + \
- MBEDTLS_SSL_PADDING_ADD \
+ MBEDTLS_SSL_PADDING_ADD + \
+ MBEDTLS_SSL_MAX_CID_EXPANSION \
)
#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \
@@ -262,11 +256,49 @@
implicit sequence number. */
#define MBEDTLS_SSL_HEADER_LEN 13
+#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define MBEDTLS_SSL_IN_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) )
+#else
+#define MBEDTLS_SSL_IN_BUFFER_LEN \
+ ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) \
+ + ( MBEDTLS_SSL_CID_IN_LEN_MAX ) )
+#endif
+#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define MBEDTLS_SSL_OUT_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) )
+#else
+#define MBEDTLS_SSL_OUT_BUFFER_LEN \
+ ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) \
+ + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
+#endif
+
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+static inline size_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
+{
+#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ return mbedtls_ssl_get_output_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ + MBEDTLS_SSL_CID_OUT_LEN_MAX;
+#else
+ return mbedtls_ssl_get_output_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
+#endif
+}
+
+static inline size_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx )
+{
+#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ return mbedtls_ssl_get_input_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ + MBEDTLS_SSL_CID_IN_LEN_MAX;
+#else
+ return mbedtls_ssl_get_input_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
+#endif
+}
+#endif
#ifdef MBEDTLS_ZLIB_SUPPORT
/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */
@@ -325,7 +357,7 @@ extern "C" {
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Abstraction for a grid of allowed signature-hash-algorithm pairs.
*/
@@ -340,7 +372,54 @@ struct mbedtls_ssl_sig_hash_set_t
mbedtls_md_type_t ecdsa;
};
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
+
+typedef int mbedtls_ssl_tls_prf_cb( const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen );
+
+/* cipher.h exports the maximum IV, key and block length from
+ * all ciphers enabled in the config, regardless of whether those
+ * ciphers are actually usable in SSL/TLS. Notably, XTS is enabled
+ * in the default configuration and uses 64 Byte keys, but it is
+ * not used for record protection in SSL/TLS.
+ *
+ * In order to prevent unnecessary inflation of key structures,
+ * we introduce SSL-specific variants of the max-{key,block,IV}
+ * macros here which are meant to only take those ciphers into
+ * account which can be negotiated in SSL/TLS.
+ *
+ * Since the current definitions of MBEDTLS_MAX_{KEY|BLOCK|IV}_LENGTH
+ * in cipher.h are rough overapproximations of the real maxima, here
+ * we content ourselves with replicating those overapproximations
+ * for the maximum block and IV length, and excluding XTS from the
+ * computation of the maximum key length. */
+#define MBEDTLS_SSL_MAX_BLOCK_LENGTH 16
+#define MBEDTLS_SSL_MAX_IV_LENGTH 16
+#define MBEDTLS_SSL_MAX_KEY_LENGTH 32
+
+/**
+ * \brief The data structure holding the cryptographic material (key and IV)
+ * used for record protection in TLS 1.3.
+ */
+struct mbedtls_ssl_key_set
+{
+ /*! The key for client->server records. */
+ unsigned char client_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ];
+ /*! The key for server->client records. */
+ unsigned char server_write_key[ MBEDTLS_SSL_MAX_KEY_LENGTH ];
+ /*! The IV for client->server records. */
+ unsigned char client_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ];
+ /*! The IV for server->client records. */
+ unsigned char server_write_iv[ MBEDTLS_SSL_MAX_IV_LENGTH ];
+
+ size_t key_len; /*!< The length of client_write_key and
+ * server_write_key, in Bytes. */
+ size_t iv_len; /*!< The length of client_write_iv and
+ * server_write_iv, in Bytes. */
+};
+typedef struct mbedtls_ssl_key_set mbedtls_ssl_key_set;
/*
* This structure contains the parameters only needed during handshake.
@@ -351,16 +430,80 @@ struct mbedtls_ssl_handshake_params
* Handshake specific crypto variables
*/
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ uint8_t max_major_ver; /*!< max. major version client*/
+ uint8_t max_minor_ver; /*!< max. minor version client*/
+ uint8_t resume; /*!< session resume indicator*/
+ uint8_t cli_exts; /*!< client extension presence*/
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ uint8_t sni_authmode; /*!< authmode from SNI callback */
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ uint8_t new_session_ticket; /*!< use NewSessionTicket? */
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ uint8_t extended_ms; /*!< use Extended Master Secret? */
+#endif
+
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ uint8_t async_in_progress; /*!< an asynchronous operation is in progress */
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ unsigned char retransmit_state; /*!< Retransmission state */
+#endif
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ uint8_t ecrs_enabled; /*!< Handshake supports EC restart? */
+ enum { /* this complements ssl->state with info on intra-state operations */
+ ssl_ecrs_none = 0, /*!< nothing going on (yet) */
+ ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */
+ ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */
+ ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */
+ ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */
+ } ecrs_state; /*!< current (or last) operation */
+ mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */
+ size_t ecrs_n; /*!< place for saving a length */
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */
#endif
+
+ size_t pmslen; /*!< premaster length */
+
+ mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
+
+ void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
+ void (*calc_verify)(const mbedtls_ssl_context *, unsigned char *, size_t *);
+ void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
+ mbedtls_ssl_tls_prf_cb *tls_prf;
+
#if defined(MBEDTLS_DHM_C)
mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */
#endif
-#if defined(MBEDTLS_ECDH_C)
+
+/* Adding guard for MBEDTLS_ECDSA_C to ensure no compile errors due
+ * to guards also being in ssl_srv.c and ssl_cli.c. There is a gap
+ * in functionality that access to ecdh_ctx structure is needed for
+ * MBEDTLS_ECDSA_C which does not seem correct.
+ */
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
-#endif
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_type_t ecdh_psa_type;
+ uint16_t ecdh_bits;
+ psa_key_id_t ecdh_psa_privkey;
+ unsigned char ecdh_psa_peerkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+ size_t ecdh_psa_peerkey_len;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
+
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */
#if defined(MBEDTLS_SSL_CLI_C)
@@ -368,56 +511,39 @@ struct mbedtls_ssl_handshake_params
size_t ecjpake_cache_len; /*!< Length of cached data */
#endif
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_key_id_t psk_opaque; /*!< Opaque PSK from the callback */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
unsigned char *psk; /*!< PSK from the callback */
size_t psk_len; /*!< Length of PSK from callback */
-#endif
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- int sni_authmode; /*!< authmode from SNI callback */
mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */
mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- int ecrs_enabled; /*!< Handshake supports EC restart? */
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */
- enum { /* this complements ssl->state with info on intra-state operations */
- ssl_ecrs_none = 0, /*!< nothing going on (yet) */
- ssl_ecrs_crt_verify, /*!< Certificate: crt_verify() */
- ssl_ecrs_ske_start_processing, /*!< ServerKeyExchange: pk_verify() */
- ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */
- ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */
- } ecrs_state; /*!< current (or last) operation */
- size_t ecrs_n; /*!< place for saving a length */
#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
- unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
-
- unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie
- Srv: unused */
- unsigned char verify_cookie_len; /*!< Cli: cookie length
- Srv: flag for sending a cookie */
- uint32_t retransmit_timeout; /*!< Current value of timeout */
- unsigned char retransmit_state; /*!< Retransmission state */
- mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */
- mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */
- unsigned char *cur_msg_p; /*!< Position in current message */
- unsigned int in_flight_start_seq; /*!< Minimum message sequence in the
- flight being received */
- mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for
- resending messages */
- unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
- for resending messages */
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
struct
{
size_t total_bytes_buffered; /*!< Cumulative size of heap allocated
@@ -444,6 +570,37 @@ struct mbedtls_ssl_handshake_params
} buffering;
+ unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
+ unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
+
+ unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie
+ Srv: unused */
+ unsigned char verify_cookie_len; /*!< Cli: cookie length
+ Srv: flag for sending a cookie */
+
+ uint32_t retransmit_timeout; /*!< Current value of timeout */
+ mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */
+ mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */
+ unsigned char *cur_msg_p; /*!< Position in current message */
+ unsigned int in_flight_start_seq; /*!< Minimum message sequence in the
+ flight being received */
+ mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for
+ resending messages */
+ unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter
+ for resending messages */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* The state of CID configuration in this handshake. */
+
+ uint8_t cid_in_use; /*!< This indicates whether the use of the CID extension
+ * has been negotiated. Possible values are
+ * #MBEDTLS_SSL_CID_ENABLED and
+ * #MBEDTLS_SSL_CID_DISABLED. */
+ unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; /*! The peer's CID */
+ uint8_t peer_cid_len; /*!< The length of
+ * \c peer_cid. */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
uint16_t mtu; /*!< Handshake mtu, used to fragment outgoing messages */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -452,47 +609,30 @@ struct mbedtls_ssl_handshake_params
*/
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_context fin_md5;
- mbedtls_sha1_context fin_sha1;
+ mbedtls_md5_context fin_md5;
+ mbedtls_sha1_context fin_sha1;
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t fin_sha256_psa;
+#else
mbedtls_sha256_context fin_sha256;
#endif
+#endif
#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t fin_sha384_psa;
+#else
mbedtls_sha512_context fin_sha512;
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t);
- void (*calc_verify)(mbedtls_ssl_context *, unsigned char *);
- void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int);
- int (*tls_prf)(const unsigned char *, size_t, const char *,
- const unsigned char *, size_t,
- unsigned char *, size_t);
-
- size_t pmslen; /*!< premaster length */
-
unsigned char randbytes[64]; /*!< random bytes */
unsigned char premaster[MBEDTLS_PREMASTER_SIZE];
/*!< premaster secret */
- int resume; /*!< session resume indicator*/
- int max_major_ver; /*!< max. major version client*/
- int max_minor_ver; /*!< max. minor version client*/
- int cli_exts; /*!< client extension presence*/
-
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- int new_session_ticket; /*!< use NewSessionTicket? */
-#endif /* MBEDTLS_SSL_SESSION_TICKETS */
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- int extended_ms; /*!< use Extended Master Secret? */
-#endif
-
-#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
- unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
-#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
-
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/** Asynchronous operation context. This field is meant for use by the
* asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
@@ -506,25 +646,120 @@ struct mbedtls_ssl_handshake_params
typedef struct mbedtls_ssl_hs_buffer mbedtls_ssl_hs_buffer;
/*
- * This structure contains a full set of runtime transform parameters
- * either in negotiation or active.
+ * Representation of decryption/encryption transformations on records
+ *
+ * There are the following general types of record transformations:
+ * - Stream transformations (TLS versions <= 1.2 only)
+ * Transformation adding a MAC and applying a stream-cipher
+ * to the authenticated message.
+ * - CBC block cipher transformations ([D]TLS versions <= 1.2 only)
+ * In addition to the distinction of the order of encryption and
+ * authentication, there's a fundamental difference between the
+ * handling in SSL3 & TLS 1.0 and TLS 1.1 and TLS 1.2: For SSL3
+ * and TLS 1.0, the final IV after processing a record is used
+ * as the IV for the next record. No explicit IV is contained
+ * in an encrypted record. The IV for the first record is extracted
+ * at key extraction time. In contrast, for TLS 1.1 and 1.2, no
+ * IV is generated at key extraction time, but every encrypted
+ * record is explicitly prefixed by the IV with which it was encrypted.
+ * - AEAD transformations ([D]TLS versions >= 1.2 only)
+ * These come in two fundamentally different versions, the first one
+ * used in TLS 1.2, excluding ChaChaPoly ciphersuites, and the second
+ * one used for ChaChaPoly ciphersuites in TLS 1.2 as well as for TLS 1.3.
+ * In the first transformation, the IV to be used for a record is obtained
+ * as the concatenation of an explicit, static 4-byte IV and the 8-byte
+ * record sequence number, and explicitly prepending this sequence number
+ * to the encrypted record. In contrast, in the second transformation
+ * the IV is obtained by XOR'ing a static IV obtained at key extraction
+ * time with the 8-byte record sequence number, without prepending the
+ * latter to the encrypted record.
+ *
+ * Additionally, DTLS 1.2 + CID as well as TLS 1.3 use an inner plaintext
+ * which allows to add flexible length padding and to hide a record's true
+ * content type.
+ *
+ * In addition to type and version, the following parameters are relevant:
+ * - The symmetric cipher algorithm to be used.
+ * - The (static) encryption/decryption keys for the cipher.
+ * - For stream/CBC, the type of message digest to be used.
+ * - For stream/CBC, (static) encryption/decryption keys for the digest.
+ * - For AEAD transformations, the size (potentially 0) of an explicit,
+ * random initialization vector placed in encrypted records.
+ * - For some transformations (currently AEAD and CBC in SSL3 and TLS 1.0)
+ * an implicit IV. It may be static (e.g. AEAD) or dynamic (e.g. CBC)
+ * and (if present) is combined with the explicit IV in a transformation-
+ * dependent way (e.g. appending in TLS 1.2 and XOR'ing in TLS 1.3).
+ * - For stream/CBC, a flag determining the order of encryption and MAC.
+ * - The details of the transformation depend on the SSL/TLS version.
+ * - The length of the authentication tag.
+ *
+ * Note: Except for CBC in SSL3 and TLS 1.0, these parameters are
+ * constant across multiple encryption/decryption operations.
+ * For CBC, the implicit IV needs to be updated after each
+ * operation.
+ *
+ * The struct below refines this abstract view as follows:
+ * - The cipher underlying the transformation is managed in
+ * cipher contexts cipher_ctx_{enc/dec}, which must have the
+ * same cipher type. The mode of these cipher contexts determines
+ * the type of the transformation in the sense above: e.g., if
+ * the type is MBEDTLS_CIPHER_AES_256_CBC resp. MBEDTLS_CIPHER_AES_192_GCM
+ * then the transformation has type CBC resp. AEAD.
+ * - The cipher keys are never stored explicitly but
+ * are maintained within cipher_ctx_{enc/dec}.
+ * - For stream/CBC transformations, the message digest contexts
+ * used for the MAC's are stored in md_ctx_{enc/dec}. These contexts
+ * are unused for AEAD transformations.
+ * - For stream/CBC transformations and versions > SSL3, the
+ * MAC keys are not stored explicitly but maintained within
+ * md_ctx_{enc/dec}.
+ * - For stream/CBC transformations and version SSL3, the MAC
+ * keys are stored explicitly in mac_enc, mac_dec and have
+ * a fixed size of 20 bytes. These fields are unused for
+ * AEAD transformations or transformations >= TLS 1.0.
+ * - For transformations using an implicit IV maintained within
+ * the transformation context, its contents are stored within
+ * iv_{enc/dec}.
+ * - The value of ivlen indicates the length of the IV.
+ * This is redundant in case of stream/CBC transformations
+ * which always use 0 resp. the cipher's block length as the
+ * IV length, but is needed for AEAD ciphers and may be
+ * different from the underlying cipher's block length
+ * in this case.
+ * - The field fixed_ivlen is nonzero for AEAD transformations only
+ * and indicates the length of the static part of the IV which is
+ * constant throughout the communication, and which is stored in
+ * the first fixed_ivlen bytes of the iv_{enc/dec} arrays.
+ * Note: For CBC in SSL3 and TLS 1.0, the fields iv_{enc/dec}
+ * still store IV's for continued use across multiple transformations,
+ * so it is not true that fixed_ivlen == 0 means that iv_{enc/dec} are
+ * not being used!
+ * - minor_ver denotes the SSL/TLS version
+ * - For stream/CBC transformations, maclen denotes the length of the
+ * authentication tag, while taglen is unused and 0.
+ * - For AEAD transformations, taglen denotes the length of the
+ * authentication tag, while maclen is unused and 0.
+ * - For CBC transformations, encrypt_then_mac determines the
+ * order of encryption and authentication. This field is unused
+ * in other transformations.
+ *
*/
struct mbedtls_ssl_transform
{
/*
* Session specific crypto layer
*/
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
- /*!< Chosen cipersuite_info */
- unsigned int keylen; /*!< symmetric key length (bytes) */
size_t minlen; /*!< min. ciphertext length */
size_t ivlen; /*!< IV length */
size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */
- size_t maclen; /*!< MAC length */
+ size_t maclen; /*!< MAC(CBC) len */
+ size_t taglen; /*!< TAG(AEAD) len */
unsigned char iv_enc[16]; /*!< IV (encryption) */
unsigned char iv_dec[16]; /*!< IV (decryption) */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+
#if defined(MBEDTLS_SSL_PROTO_SSL3)
/* Needed only for SSL v3.0 secret */
unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */
@@ -534,8 +769,22 @@ struct mbedtls_ssl_transform
mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */
mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ int encrypt_then_mac; /*!< flag for EtM activation */
+#endif
+
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+
mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */
mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */
+ int minor_ver;
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ uint8_t in_cid_len;
+ uint8_t out_cid_len;
+ unsigned char in_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+ unsigned char out_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
/*
* Session specific compression layer
@@ -544,8 +793,83 @@ struct mbedtls_ssl_transform
z_stream ctx_deflate; /*!< compression context */
z_stream ctx_inflate; /*!< decompression context */
#endif
+
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+ /* We need the Hello random bytes in order to re-derive keys from the
+ * Master Secret and other session info, see ssl_populate_transform() */
+ unsigned char randbytes[64]; /*!< ServerHello.random+ClientHello.random */
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
};
+/*
+ * Return 1 if the transform uses an AEAD cipher, 0 otherwise.
+ * Equivalently, return 0 if a separate MAC is used, 1 otherwise.
+ */
+static inline int mbedtls_ssl_transform_uses_aead(
+ const mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ return( transform->maclen == 0 && transform->taglen != 0 );
+#else
+ (void) transform;
+ return( 1 );
+#endif
+}
+
+/*
+ * Internal representation of record frames
+ *
+ * Instances come in two flavors:
+ * (1) Encrypted
+ * These always have data_offset = 0
+ * (2) Unencrypted
+ * These have data_offset set to the amount of
+ * pre-expansion during record protection. Concretely,
+ * this is the length of the fixed part of the explicit IV
+ * used for encryption, or 0 if no explicit IV is used
+ * (e.g. for CBC in TLS 1.0, or stream ciphers).
+ *
+ * The reason for the data_offset in the unencrypted case
+ * is to allow for in-place conversion of an unencrypted to
+ * an encrypted record. If the offset wasn't included, the
+ * encrypted content would need to be shifted afterwards to
+ * make space for the fixed IV.
+ *
+ */
+#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX
+#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_OUT_LEN_MAX
+#else
+#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_IN_LEN_MAX
+#endif
+
+typedef struct
+{
+ uint8_t ctr[8]; /* In TLS: The implicit record sequence number.
+ * In DTLS: The 2-byte epoch followed by
+ * the 6-byte sequence number.
+ * This is stored as a raw big endian byte array
+ * as opposed to a uint64_t because we rarely
+ * need to perform arithmetic on this, but do
+ * need it as a Byte array for the purpose of
+ * MAC computations. */
+ uint8_t type; /* The record content type. */
+ uint8_t ver[2]; /* SSL/TLS version as present on the wire.
+ * Convert to internal presentation of versions
+ * using mbedtls_ssl_read_version() and
+ * mbedtls_ssl_write_version().
+ * Keep wire-format for MAC computations. */
+
+ unsigned char *buf; /* Memory buffer enclosing the record content */
+ size_t buf_len; /* Buffer length */
+ size_t data_offset; /* Offset of record content */
+ size_t data_len; /* Length of record content */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ uint8_t cid_len; /* Length of the CID (0 if not present) */
+ unsigned char cid[ MBEDTLS_SSL_CID_LEN_MAX ]; /* The CID */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+} mbedtls_record;
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/*
* List of certificate + private key pairs
@@ -572,7 +896,7 @@ struct mbedtls_ssl_flight_item
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* Find an entry in a signature-hash set matching a given hash algorithm. */
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
@@ -592,7 +916,7 @@ static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *se
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/**
* \brief Free referenced items in an SSL transform context and clear
@@ -719,9 +1043,62 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl );
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex );
-#endif
+
+/**
+ * Get the first defined PSK by order of precedence:
+ * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk() in the PSK callback
+ * 2. static PSK configured by \c mbedtls_ssl_conf_psk()
+ * Return a code and update the pair (PSK, PSK length) passed to this function
+ */
+static inline int mbedtls_ssl_get_psk( const mbedtls_ssl_context *ssl,
+ const unsigned char **psk, size_t *psk_len )
+{
+ if( ssl->handshake->psk != NULL && ssl->handshake->psk_len > 0 )
+ {
+ *psk = ssl->handshake->psk;
+ *psk_len = ssl->handshake->psk_len;
+ }
+
+ else if( ssl->conf->psk != NULL && ssl->conf->psk_len > 0 )
+ {
+ *psk = ssl->conf->psk;
+ *psk_len = ssl->conf->psk_len;
+ }
+
+ else
+ {
+ *psk = NULL;
+ *psk_len = 0;
+ return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ }
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/**
+ * Get the first defined opaque PSK by order of precedence:
+ * 1. handshake PSK set by \c mbedtls_ssl_set_hs_psk_opaque() in the PSK
+ * callback
+ * 2. static PSK configured by \c mbedtls_ssl_conf_psk_opaque()
+ * Return an opaque PSK
+ */
+static inline psa_key_id_t mbedtls_ssl_get_opaque_psk(
+ const mbedtls_ssl_context *ssl )
+{
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ return( ssl->handshake->psk_opaque );
+
+ if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+ return( ssl->conf->psk_opaque );
+
+ return( MBEDTLS_SVC_KEY_ID_INIT );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_PK_C)
unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk );
@@ -737,11 +1114,28 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md );
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
mbedtls_md_type_t md );
#endif
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static inline mbedtls_ssl_srtp_profile mbedtls_ssl_check_srtp_profile_value
+ ( const uint16_t srtp_profile_value )
+{
+ switch( srtp_profile_value )
+ {
+ case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80:
+ case MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_32:
+ case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_80:
+ case MBEDTLS_TLS_SRTP_NULL_HMAC_SHA1_32:
+ return srtp_profile_value;
+ default: break;
+ }
+ return( MBEDTLS_TLS_SRTP_UNSET );
+}
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl )
{
@@ -787,15 +1181,27 @@ void mbedtls_ssl_write_version( int major, int minor, int transport,
void mbedtls_ssl_read_version( int *major, int *minor, int transport,
const unsigned char ver[2] );
-static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl )
+static inline size_t mbedtls_ssl_in_hdr_len( const mbedtls_ssl_context *ssl )
{
+#if !defined(MBEDTLS_SSL_PROTO_DTLS)
+ ((void) ssl);
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
return( 13 );
-#else
- ((void) ssl);
-#endif
- return( 5 );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ return( 5 );
+ }
+}
+
+static inline size_t mbedtls_ssl_out_hdr_len( const mbedtls_ssl_context *ssl )
+{
+ return( (size_t) ( ssl->out_iv - ssl->out_hdr ) );
}
static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
@@ -818,29 +1224,12 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
/* Visible for testing purposes only */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl );
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl );
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
#endif
-/* constant-time buffer comparison */
-static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- volatile const unsigned char *A = (volatile const unsigned char *) a;
- volatile const unsigned char *B = (volatile const unsigned char *) b;
- volatile unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- {
- /* Read volatile data in order before computing diff.
- * This avoids IAR compiler warning:
- * 'the order of volatile accesses is undefined ..' */
- unsigned char x = A[i], y = B[i];
- diff |= x ^ y;
- }
-
- return( diff );
-}
+int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
+ const mbedtls_ssl_session *src );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
@@ -852,6 +1241,7 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
+/* The hash buffer must have at least MBEDTLS_MD_MAX_SIZE bytes of length. */
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
@@ -859,75 +1249,60 @@ 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
+void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform );
+int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec );
+
+/* Length of the "epoch" field in the record header */
+static inline size_t mbedtls_ssl_ep_len( const mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( 2 );
+#else
+ ((void) ssl);
+#endif
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs );
+int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl );
+
+void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform );
+void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
+#endif
+
+void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+int mbedtls_ssl_start_renegotiation( mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+size_t mbedtls_ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
+void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl );
+void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
#endif /* ssl_internal.h */
diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
index a83f5e6662..a882eed23b 100644
--- a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
+++ b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_SSL_TICKET_H
#define MBEDTLS_SSL_TICKET_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -61,11 +34,11 @@
* secrecy, when MBEDTLS_HAVE_TIME is defined.
*/
-#include "ssl.h"
-#include "cipher.h"
+#include "mbedtls/ssl.h"
+#include "mbedtls/cipher.h"
#if defined(MBEDTLS_THREADING_C)
-#include "threading.h"
+#include "mbedtls/threading.h"
#endif
#ifdef __cplusplus
diff --git a/thirdparty/mbedtls/include/mbedtls/threading.h b/thirdparty/mbedtls/include/mbedtls/threading.h
index 2cf0716715..d147c73f06 100644
--- a/thirdparty/mbedtls/include/mbedtls/threading.h
+++ b/thirdparty/mbedtls/include/mbedtls/threading.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_THREADING_H
#define MBEDTLS_THREADING_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/timing.h b/thirdparty/mbedtls/include/mbedtls/timing.h
index 8611ba9a4e..b7290cfcab 100644
--- a/thirdparty/mbedtls/include/mbedtls/timing.h
+++ b/thirdparty/mbedtls/include/mbedtls/timing.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_TIMING_H
#define MBEDTLS_TIMING_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h
index 35955a61d3..b1a92b2bcf 100644
--- a/thirdparty/mbedtls/include/mbedtls/version.h
+++ b/thirdparty/mbedtls/include/mbedtls/version.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,27 +18,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* This set of compile-time defines and run-time variables can be used to
@@ -54,7 +27,7 @@
#define MBEDTLS_VERSION_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
@@ -64,17 +37,17 @@
* Major, Minor, Patchlevel
*/
#define MBEDTLS_VERSION_MAJOR 2
-#define MBEDTLS_VERSION_MINOR 16
-#define MBEDTLS_VERSION_PATCH 12
+#define MBEDTLS_VERSION_MINOR 28
+#define MBEDTLS_VERSION_PATCH 0
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02100C00
-#define MBEDTLS_VERSION_STRING "2.16.12"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.12"
+#define MBEDTLS_VERSION_NUMBER 0x021C0000
+#define MBEDTLS_VERSION_STRING "2.28.0"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.28.0"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/include/mbedtls/x509.h b/thirdparty/mbedtls/include/mbedtls/x509.h
index fea435715d..c177501430 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,42 +18,21 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_X509_H
#define MBEDTLS_X509_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "asn1.h"
-#include "pk.h"
+#include "mbedtls/asn1.h"
+#include "mbedtls/pk.h"
#if defined(MBEDTLS_RSA_C)
-#include "rsa.h"
+#include "mbedtls/rsa.h"
#endif
/**
@@ -155,6 +128,28 @@
/* \} addtogroup x509_module */
/*
+ * X.509 v3 Subject Alternative Name types.
+ * otherName [0] OtherName,
+ * rfc822Name [1] IA5String,
+ * dNSName [2] IA5String,
+ * x400Address [3] ORAddress,
+ * directoryName [4] Name,
+ * ediPartyName [5] EDIPartyName,
+ * uniformResourceIdentifier [6] IA5String,
+ * iPAddress [7] OCTET STRING,
+ * registeredID [8] OBJECT IDENTIFIER
+ */
+#define MBEDTLS_X509_SAN_OTHER_NAME 0
+#define MBEDTLS_X509_SAN_RFC822_NAME 1
+#define MBEDTLS_X509_SAN_DNS_NAME 2
+#define MBEDTLS_X509_SAN_X400_ADDRESS_NAME 3
+#define MBEDTLS_X509_SAN_DIRECTORY_NAME 4
+#define MBEDTLS_X509_SAN_EDI_PARTY_NAME 5
+#define MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER 6
+#define MBEDTLS_X509_SAN_IP_ADDRESS 7
+#define MBEDTLS_X509_SAN_REGISTERED_ID 8
+
+/*
* X.509 v3 Key Usage Extension flags
* Reminder: update x509_info_key_usage() when adding new flags.
*/
@@ -187,24 +182,26 @@
*
* Comments refer to the status for using certificates. Status can be
* different for writing certificates or reading CRLs or CSRs.
+ *
+ * Those are defined in oid.h as oid.c needs them in a data structure. Since
+ * these were previously defined here, let's have aliases for compatibility.
*/
-#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0)
-#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER (1 << 1)
-#define MBEDTLS_X509_EXT_KEY_USAGE (1 << 2)
-#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES (1 << 3)
-#define MBEDTLS_X509_EXT_POLICY_MAPPINGS (1 << 4)
-#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME (1 << 5) /* Supported (DNS) */
-#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME (1 << 6)
-#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7)
-#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS (1 << 8) /* Supported */
-#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS (1 << 9)
-#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS (1 << 10)
-#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE (1 << 11)
-#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS (1 << 12)
-#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13)
-#define MBEDTLS_X509_EXT_FRESHEST_CRL (1 << 14)
-
-#define MBEDTLS_X509_EXT_NS_CERT_TYPE (1 << 16)
+#define MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER
+#define MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER MBEDTLS_OID_X509_EXT_SUBJECT_KEY_IDENTIFIER
+#define MBEDTLS_X509_EXT_KEY_USAGE MBEDTLS_OID_X509_EXT_KEY_USAGE
+#define MBEDTLS_X509_EXT_CERTIFICATE_POLICIES MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES
+#define MBEDTLS_X509_EXT_POLICY_MAPPINGS MBEDTLS_OID_X509_EXT_POLICY_MAPPINGS
+#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME /* Supported (DNS) */
+#define MBEDTLS_X509_EXT_ISSUER_ALT_NAME MBEDTLS_OID_X509_EXT_ISSUER_ALT_NAME
+#define MBEDTLS_X509_EXT_SUBJECT_DIRECTORY_ATTRS MBEDTLS_OID_X509_EXT_SUBJECT_DIRECTORY_ATTRS
+#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS /* Supported */
+#define MBEDTLS_X509_EXT_NAME_CONSTRAINTS MBEDTLS_OID_X509_EXT_NAME_CONSTRAINTS
+#define MBEDTLS_X509_EXT_POLICY_CONSTRAINTS MBEDTLS_OID_X509_EXT_POLICY_CONSTRAINTS
+#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE
+#define MBEDTLS_X509_EXT_CRL_DISTRIBUTION_POINTS MBEDTLS_OID_X509_EXT_CRL_DISTRIBUTION_POINTS
+#define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY MBEDTLS_OID_X509_EXT_INIHIBIT_ANYPOLICY
+#define MBEDTLS_X509_EXT_FRESHEST_CRL MBEDTLS_OID_X509_EXT_FRESHEST_CRL
+#define MBEDTLS_X509_EXT_NS_CERT_TYPE MBEDTLS_OID_X509_EXT_NS_CERT_TYPE
/*
* Storage format identifiers
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crl.h b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
index 2ade47c89d..7e9e8885f4 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crl.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crl.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,38 +18,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_X509_CRL_H
#define MBEDTLS_X509_CRL_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "x509.h"
+#include "mbedtls/x509.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crt.h b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
index 30da1909b7..64ccb433ba 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_crt.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_crt.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,39 +18,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_X509_CRT_H
#define MBEDTLS_X509_CRT_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "x509.h"
-#include "x509_crl.h"
+#include "mbedtls/x509.h"
+#include "mbedtls/x509_crl.h"
+#include "mbedtls/bignum.h"
/**
* \addtogroup x509_module
@@ -77,6 +51,8 @@ extern "C" {
*/
typedef struct mbedtls_x509_crt
{
+ int own_buffer; /**< Indicates if \c raw is owned
+ * by the structure or not. */
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
@@ -93,12 +69,15 @@ typedef struct mbedtls_x509_crt
mbedtls_x509_time valid_from; /**< Start time of certificate validity. */
mbedtls_x509_time valid_to; /**< End time of certificate validity. */
+ mbedtls_x509_buf pk_raw;
mbedtls_pk_context pk; /**< Container for the public key context. */
mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */
mbedtls_x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */
mbedtls_x509_buf v3_ext; /**< Optional X.509 v3 extensions. */
- mbedtls_x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */
+ mbedtls_x509_sequence subject_alt_names; /**< Optional list of raw entries of Subject Alternative Names extension (currently only dNSName and OtherName are listed). */
+
+ mbedtls_x509_sequence certificate_policies; /**< Optional list of certificate policies (Only anyPolicy is printed and enforced, however the rest of the policies are still listed). */
int ext_types; /**< Bit string containing detected and parsed extensions */
int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
@@ -120,6 +99,53 @@ typedef struct mbedtls_x509_crt
mbedtls_x509_crt;
/**
+ * From RFC 5280 section 4.2.1.6:
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ */
+typedef struct mbedtls_x509_san_other_name
+{
+ /**
+ * The type_id is an OID as deifned in RFC 5280.
+ * To check the value of the type id, you should use
+ * \p MBEDTLS_OID_CMP with a known OID mbedtls_x509_buf.
+ */
+ mbedtls_x509_buf type_id; /**< The type id. */
+ union
+ {
+ /**
+ * From RFC 4108 section 5:
+ * HardwareModuleName ::= SEQUENCE {
+ * hwType OBJECT IDENTIFIER,
+ * hwSerialNum OCTET STRING }
+ */
+ struct
+ {
+ mbedtls_x509_buf oid; /**< The object identifier. */
+ mbedtls_x509_buf val; /**< The named value. */
+ }
+ hardware_module_name;
+ }
+ value;
+}
+mbedtls_x509_san_other_name;
+
+/**
+ * A structure for holding the parsed Subject Alternative Name, according to type
+ */
+typedef struct mbedtls_x509_subject_alternative_name
+{
+ int type; /**< The SAN type, value of MBEDTLS_X509_SAN_XXX. */
+ union {
+ mbedtls_x509_san_other_name other_name; /**< The otherName supported type. */
+ mbedtls_x509_buf unstructured_name; /**< The buffer for the un constructed types. Only dnsName currently supported */
+ }
+ san; /**< A union of the supported SAN types */
+}
+mbedtls_x509_subject_alternative_name;
+
+/**
* Build flag from an algorithm/curve identifier (pk, md, ecp)
* Since 0 is always XXX_NONE, ignore it.
*/
@@ -188,6 +214,14 @@ typedef struct
{
mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE];
unsigned len;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ /* This stores the list of potential trusted signers obtained from
+ * the CA callback used for the CRT verification, if configured.
+ * We must track it somewhere because the callback passes its
+ * ownership to the caller. */
+ mbedtls_x509_crt *trust_ca_cb_result;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
} mbedtls_x509_crt_verify_chain;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
@@ -254,16 +288,142 @@ extern const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb;
/**
* \brief Parse a single DER formatted certificate and add it
- * to the chained list.
- *
- * \param chain points to the start of the chain
- * \param buf buffer holding the certificate DER data
- * \param buflen size of the buffer
- *
- * \return 0 if successful, or a specific X509 or PEM error code
+ * to the end of the provided chained list.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The buffer holding the DER encoded certificate.
+ * \param buflen The size in Bytes of \p buf.
+ *
+ * \note This function makes an internal copy of the CRT buffer
+ * \p buf. In particular, \p buf may be destroyed or reused
+ * after this call returns. To avoid duplicating the CRT
+ * buffer (at the cost of stricter lifetime constraints),
+ * use mbedtls_x509_crt_parse_der_nocopy() instead.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
+ */
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
+
+/**
+ * \brief The type of certificate extension callbacks.
+ *
+ * Callbacks of this type are passed to and used by the
+ * mbedtls_x509_crt_parse_der_with_ext_cb() routine when
+ * it encounters either an unsupported extension or a
+ * "certificate policies" extension containing any
+ * unsupported certificate policies.
+ * Future versions of the library may invoke the callback
+ * in other cases, if and when the need arises.
+ *
+ * \param p_ctx An opaque context passed to the callback.
+ * \param crt The certificate being parsed.
+ * \param oid The OID of the extension.
+ * \param critical Whether the extension is critical.
+ * \param p Pointer to the start of the extension value
+ * (the content of the OCTET STRING).
+ * \param end End of extension value.
+ *
+ * \note The callback must fail and return a negative error code
+ * if it can not parse or does not support the extension.
+ * When the callback fails to parse a critical extension
+ * mbedtls_x509_crt_parse_der_with_ext_cb() also fails.
+ * When the callback fails to parse a non critical extension
+ * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips
+ * the extension and continues parsing.
+ *
+ * \return \c 0 on success.
+ * \return A negative error code on failure.
+ */
+typedef int (*mbedtls_x509_crt_ext_cb_t)( void *p_ctx,
+ mbedtls_x509_crt const *crt,
+ mbedtls_x509_buf const *oid,
+ int critical,
+ const unsigned char *p,
+ const unsigned char *end );
+
+/**
+ * \brief Parse a single DER formatted certificate and add it
+ * to the end of the provided chained list.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The buffer holding the DER encoded certificate.
+ * \param buflen The size in Bytes of \p buf.
+ * \param make_copy When not zero this function makes an internal copy of the
+ * CRT buffer \p buf. In particular, \p buf may be destroyed
+ * or reused after this call returns.
+ * When zero this function avoids duplicating the CRT buffer
+ * by taking temporary ownership thereof until the CRT
+ * is destroyed (like mbedtls_x509_crt_parse_der_nocopy())
+ * \param cb A callback invoked for every unsupported certificate
+ * extension.
+ * \param p_ctx An opaque context passed to the callback.
+ *
+ * \note This call is functionally equivalent to
+ * mbedtls_x509_crt_parse_der(), and/or
+ * mbedtls_x509_crt_parse_der_nocopy()
+ * but it calls the callback with every unsupported
+ * certificate extension and additionally the
+ * "certificate policies" extension if it contains any
+ * unsupported certificate policies.
+ * The callback must return a negative error code if it
+ * does not know how to handle such an extension.
+ * When the callback fails to parse a critical extension
+ * mbedtls_x509_crt_parse_der_with_ext_cb() also fails.
+ * When the callback fails to parse a non critical extension
+ * mbedtls_x509_crt_parse_der_with_ext_cb() simply skips
+ * the extension and continues parsing.
+ * Future versions of the library may invoke the callback
+ * in other cases, if and when the need arises.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
+ */
+int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx );
+
+/**
+ * \brief Parse a single DER formatted certificate and add it
+ * to the end of the provided chained list. This is a
+ * variant of mbedtls_x509_crt_parse_der() which takes
+ * temporary ownership of the CRT buffer until the CRT
+ * is destroyed.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The address of the readable buffer holding the DER encoded
+ * certificate to use. On success, this buffer must be
+ * retained and not be changed for the liftetime of the
+ * CRT chain \p chain, that is, until \p chain is destroyed
+ * through a call to mbedtls_x509_crt_free().
+ * \param buflen The size in Bytes of \p buf.
+ *
+ * \note This call is functionally equivalent to
+ * mbedtls_x509_crt_parse_der(), but it avoids creating a
+ * copy of the input buffer at the cost of stronger lifetime
+ * constraints. This is useful in constrained environments
+ * where duplication of the CRT cannot be tolerated.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
*/
-int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen );
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
/**
* \brief Parse one DER-encoded or one or more concatenated PEM-encoded
@@ -327,8 +487,37 @@ int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path );
* if partly successful or a specific X509 or PEM error code
*/
int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path );
-#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_FS_IO */
+/**
+ * \brief This function parses an item in the SubjectAlternativeNames
+ * extension.
+ *
+ * \param san_buf The buffer holding the raw data item of the subject
+ * alternative name.
+ * \param san The target structure to populate with the parsed presentation
+ * of the subject alternative name encoded in \p san_raw.
+ *
+ * \note Only "dnsName" and "otherName" of type hardware_module_name
+ * as defined in RFC 4180 is supported.
+ *
+ * \note This function should be called on a single raw data of
+ * subject alternative name. For example, after successful
+ * certificate parsing, one must iterate on every item in the
+ * \p crt->subject_alt_names sequence, and pass it to
+ * this function.
+ *
+ * \warning The target structure contains pointers to the raw data of the
+ * parsed certificate, and its lifetime is restricted by the
+ * lifetime of the certificate.
+ *
+ * \return \c 0 on success
+ * \return #MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE for an unsupported
+ * SAN type.
+ * \return Another negative value for any other failure.
+ */
+int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf,
+ mbedtls_x509_subject_alternative_name *san );
/**
* \brief Returns an informational string about the
* certificate.
@@ -360,7 +549,7 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
uint32_t flags );
/**
- * \brief Verify the certificate signature
+ * \brief Verify a chain of certificates.
*
* The verify callback is a user-supplied callback that
* can clear / modify / add flags for a certificate. If set,
@@ -400,22 +589,30 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
* specific peers you know) - in that case, the self-signed
* certificate doesn't need to have the CA bit set.
*
- * \param crt a certificate (chain) to be verified
- * \param trust_ca the list of trusted CAs (see note above)
- * \param ca_crl the list of CRLs for trusted CAs (see note above)
- * \param cn expected Common Name (can be set to
- * NULL if the CN must not be verified)
- * \param flags result of the verification
- * \param f_vrfy verification function
- * \param p_vrfy verification parameter
- *
- * \return 0 (and flags set to 0) if the chain was verified and valid,
- * MBEDTLS_ERR_X509_CERT_VERIFY_FAILED if the chain was verified
- * but found to be invalid, in which case *flags will have one
- * or more MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX
- * flags set, or another error (and flags set to 0xffffffff)
- * in case of a fatal error encountered during the
- * verification process.
+ * \param crt The certificate chain to be verified.
+ * \param trust_ca The list of trusted CAs.
+ * \param ca_crl The list of CRLs for trusted CAs.
+ * \param cn The expected Common Name. This will be checked to be
+ * present in the certificate's subjectAltNames extension or,
+ * if this extension is absent, as a CN component in its
+ * Subject name. Currently only DNS names are supported. This
+ * may be \c NULL if the CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return \c 0 if the chain is valid with respect to the
+ * passed CN, CAs, CRLs and security profile.
+ * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the
+ * certificate chain verification failed. In this case,
+ * \c *flags will have one or more
+ * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX
+ * flags set.
+ * \return Another negative error code in case of a fatal error
+ * encountered during the verification process.
*/
int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
@@ -425,7 +622,8 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
void *p_vrfy );
/**
- * \brief Verify the certificate signature according to profile
+ * \brief Verify a chain of certificates with respect to
+ * a configurable security profile.
*
* \note Same as \c mbedtls_x509_crt_verify(), but with explicit
* security profile.
@@ -434,22 +632,28 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
* for ECDSA) apply to all certificates: trusted root,
* intermediate CAs if any, and end entity certificate.
*
- * \param crt a certificate (chain) to be verified
- * \param trust_ca the list of trusted CAs
- * \param ca_crl the list of CRLs for trusted CAs
- * \param profile security profile for verification
- * \param cn expected Common Name (can be set to
- * NULL if the CN must not be verified)
- * \param flags result of the verification
- * \param f_vrfy verification function
- * \param p_vrfy verification parameter
- *
- * \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
- * in which case *flags will have one or more
- * MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags
- * set,
- * or another error in case of a fatal error encountered
- * during the verification process.
+ * \param crt The certificate chain to be verified.
+ * \param trust_ca The list of trusted CAs.
+ * \param ca_crl The list of CRLs for trusted CAs.
+ * \param profile The security profile to use for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return \c 0 if the chain is valid with respect to the
+ * passed CN, CAs, CRLs and security profile.
+ * \return #MBEDTLS_ERR_X509_CERT_VERIFY_FAILED in case the
+ * certificate chain verification failed. In this case,
+ * \c *flags will have one or more
+ * \c MBEDTLS_X509_BADCERT_XXX or \c MBEDTLS_X509_BADCRL_XXX
+ * flags set.
+ * \return Another negative error code in case of a fatal error
+ * encountered during the verification process.
*/
int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
@@ -466,16 +670,20 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
* but can return early and restart according to the limit
* set with \c mbedtls_ecp_set_max_ops() to reduce blocking.
*
- * \param crt a certificate (chain) to be verified
- * \param trust_ca the list of trusted CAs
- * \param ca_crl the list of CRLs for trusted CAs
- * \param profile security profile for verification
- * \param cn expected Common Name (can be set to
- * NULL if the CN must not be verified)
- * \param flags result of the verification
- * \param f_vrfy verification function
- * \param p_vrfy verification parameter
- * \param rs_ctx restart context (NULL to disable restart)
+ * \param crt The certificate chain to be verified.
+ * \param trust_ca The list of trusted CAs.
+ * \param ca_crl The list of CRLs for trusted CAs.
+ * \param profile The security profile to use for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ * \param rs_ctx The restart context to use. This may be set to \c NULL
+ * to disable restartable ECC.
*
* \return See \c mbedtls_crt_verify_with_profile(), or
* \return #MBEDTLS_ERR_ECP_IN_PROGRESS if maximum number of
@@ -490,6 +698,73 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx );
+/**
+ * \brief The type of trusted certificate callbacks.
+ *
+ * Callbacks of this type are passed to and used by the CRT
+ * verification routine mbedtls_x509_crt_verify_with_ca_cb()
+ * when looking for trusted signers of a given certificate.
+ *
+ * On success, the callback returns a list of trusted
+ * certificates to be considered as potential signers
+ * for the input certificate.
+ *
+ * \param p_ctx An opaque context passed to the callback.
+ * \param child The certificate for which to search a potential signer.
+ * This will point to a readable certificate.
+ * \param candidate_cas The address at which to store the address of the first
+ * entry in the generated linked list of candidate signers.
+ * This will not be \c NULL.
+ *
+ * \note The callback must only return a non-zero value on a
+ * fatal error. If, in contrast, the search for a potential
+ * signer completes without a single candidate, the
+ * callback must return \c 0 and set \c *candidate_cas
+ * to \c NULL.
+ *
+ * \return \c 0 on success. In this case, \c *candidate_cas points
+ * to a heap-allocated linked list of instances of
+ * ::mbedtls_x509_crt, and ownership of this list is passed
+ * to the caller.
+ * \return A negative error code on failure.
+ */
+typedef int (*mbedtls_x509_crt_ca_cb_t)( void *p_ctx,
+ mbedtls_x509_crt const *child,
+ mbedtls_x509_crt **candidate_cas );
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/**
+ * \brief Version of \c mbedtls_x509_crt_verify_with_profile() which
+ * uses a callback to acquire the list of trusted CA
+ * certificates.
+ *
+ * \param crt The certificate chain to be verified.
+ * \param f_ca_cb The callback to be used to query for potential signers
+ * of a given child certificate. See the documentation of
+ * ::mbedtls_x509_crt_ca_cb_t for more information.
+ * \param p_ca_cb The opaque context to be passed to \p f_ca_cb.
+ * \param profile The security profile for the verification.
+ * \param cn The expected Common Name. This may be \c NULL if the
+ * CN need not be verified.
+ * \param flags The address at which to store the result of the verification.
+ * If the verification couldn't be completed, the flag value is
+ * set to (uint32_t) -1.
+ * \param f_vrfy The verification callback to use. See the documentation
+ * of mbedtls_x509_crt_verify() for more information.
+ * \param p_vrfy The context to be passed to \p f_vrfy.
+ *
+ * \return See \c mbedtls_crt_verify_with_profile().
+ */
+int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy );
+
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
/**
* \brief Check usage of certificate against keyUsage extension.
diff --git a/thirdparty/mbedtls/include/mbedtls/x509_csr.h b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
index 5dfb4213e8..b1dfc21f1f 100644
--- a/thirdparty/mbedtls/include/mbedtls/x509_csr.h
+++ b/thirdparty/mbedtls/include/mbedtls/x509_csr.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,38 +18,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_X509_CSR_H
#define MBEDTLS_X509_CSR_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
-#include "x509.h"
+#include "mbedtls/x509.h"
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/mbedtls/include/mbedtls/xtea.h b/thirdparty/mbedtls/include/mbedtls/xtea.h
index 41a1bc85fc..4bdc711fda 100644
--- a/thirdparty/mbedtls/include/mbedtls/xtea.h
+++ b/thirdparty/mbedtls/include/mbedtls/xtea.h
@@ -5,13 +5,7 @@
*/
/*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -24,33 +18,12 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#ifndef MBEDTLS_XTEA_H
#define MBEDTLS_XTEA_H
#if !defined(MBEDTLS_CONFIG_FILE)
-#include "config.h"
+#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c
index af19a3849f..31824e75cf 100644
--- a/thirdparty/mbedtls/library/aes.c
+++ b/thirdparty/mbedtls/library/aes.c
@@ -2,13 +2,7 @@
* FIPS-197 compliant AES implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
@@ -50,11 +23,7 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_AES_C)
@@ -63,6 +32,7 @@
#include "mbedtls/aes.h"
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_PADLOCK_C)
#include "mbedtls/padlock.h"
#endif
@@ -87,29 +57,6 @@
#define AES_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
#if defined(MBEDTLS_PADLOCK_C) && \
( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
static int aes_padlock_ace = -1;
@@ -439,7 +386,7 @@ static void aes_gen_tables( void )
{
pow[i] = x;
log[x] = i;
- x = ( x ^ XTIME( x ) ) & 0xFF;
+ x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
}
/*
@@ -448,7 +395,7 @@ static void aes_gen_tables( void )
for( i = 0, x = 1; i < 10; i++ )
{
RCON[i] = (uint32_t) x;
- x = XTIME( x ) & 0xFF;
+ x = MBEDTLS_BYTE_0( XTIME( x ) );
}
/*
@@ -461,10 +408,10 @@ static void aes_gen_tables( void )
{
x = pow[255 - log[i]];
- y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
- x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
+ x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
x ^= y ^ 0x63;
FSb[i] = (unsigned char) x;
@@ -477,8 +424,8 @@ static void aes_gen_tables( void )
for( i = 0; i < 256; i++ )
{
x = FSb[i];
- y = XTIME( x ) & 0xFF;
- z = ( y ^ x ) & 0xFF;
+ y = MBEDTLS_BYTE_0( XTIME( x ) );
+ z = MBEDTLS_BYTE_0( y ^ x );
FT0[i] = ( (uint32_t) y ) ^
( (uint32_t) x << 8 ) ^
@@ -620,7 +567,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < ( keybits >> 5 ); i++ )
{
- GET_UINT32_LE( RK[i], key, i << 2 );
+ RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
}
switch( ctx->nr )
@@ -630,10 +577,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 10; i++, RK += 4 )
{
RK[4] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
RK[5] = RK[1] ^ RK[4];
RK[6] = RK[2] ^ RK[5];
@@ -646,10 +593,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 8; i++, RK += 6 )
{
RK[6] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
RK[7] = RK[1] ^ RK[6];
RK[8] = RK[2] ^ RK[7];
@@ -664,20 +611,20 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
for( i = 0; i < 7; i++, RK += 8 )
{
RK[8] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
RK[9] = RK[1] ^ RK[8];
RK[10] = RK[2] ^ RK[9];
RK[11] = RK[3] ^ RK[10];
RK[12] = RK[4] ^
- ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
RK[13] = RK[5] ^ RK[12];
RK[14] = RK[6] ^ RK[13];
@@ -743,10 +690,10 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
{
for( j = 0; j < 4; j++, SK++ )
{
- *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
- AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
- AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
- AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
+ *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
+ AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
+ AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
+ AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
}
}
@@ -792,7 +739,7 @@ int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
@@ -817,7 +764,7 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *key1, *key2;
unsigned int key1bits, key2bits;
@@ -839,52 +786,52 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
-#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
- do \
- { \
- (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
- AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
- \
- (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
- AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
- \
- (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
- AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
- \
- (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
- AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+ do \
+ { \
+ (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
+ \
+ (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
+ \
+ (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
+ \
+ (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
+ AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
+ AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
+ AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
} while( 0 )
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
do \
{ \
- (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
- AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
+ (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
\
- (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
- AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
+ (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
\
- (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
- AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
+ (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
\
- (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
- AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
- AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
- AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
+ (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
+ AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
+ AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
+ AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
} while( 0 )
/*
@@ -903,10 +850,10 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
uint32_t Y[4];
} t;
- GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
- GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
- GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
- GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+ t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
+ t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
+ t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
+ t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
@@ -917,33 +864,33 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[0] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
t.X[1] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[1] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
t.X[2] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[2] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
t.X[3] = *RK++ ^ \
- ( (uint32_t) FSb[ ( t.Y[3] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+ ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
- PUT_UINT32_LE( t.X[0], output, 0 );
- PUT_UINT32_LE( t.X[1], output, 4 );
- PUT_UINT32_LE( t.X[2], output, 8 );
- PUT_UINT32_LE( t.X[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
@@ -956,7 +903,7 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
- mbedtls_internal_aes_encrypt( ctx, input, output );
+ MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
@@ -976,10 +923,10 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
uint32_t Y[4];
} t;
- GET_UINT32_LE( t.X[0], input, 0 ); t.X[0] ^= *RK++;
- GET_UINT32_LE( t.X[1], input, 4 ); t.X[1] ^= *RK++;
- GET_UINT32_LE( t.X[2], input, 8 ); t.X[2] ^= *RK++;
- GET_UINT32_LE( t.X[3], input, 12 ); t.X[3] ^= *RK++;
+ t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
+ t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
+ t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
+ t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
{
@@ -990,33 +937,33 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
t.X[0] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[0] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
t.X[1] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[1] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
t.X[2] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[2] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[3] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
t.X[3] = *RK++ ^ \
- ( (uint32_t) RSb[ ( t.Y[3] ) & 0xFF ] ) ^
- ( (uint32_t) RSb[ ( t.Y[2] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) RSb[ ( t.Y[1] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) RSb[ ( t.Y[0] >> 24 ) & 0xFF ] << 24 );
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
+ ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
- PUT_UINT32_LE( t.X[0], output, 0 );
- PUT_UINT32_LE( t.X[1], output, 4 );
- PUT_UINT32_LE( t.X[2], output, 8 );
- PUT_UINT32_LE( t.X[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
mbedtls_platform_zeroize( &t, sizeof( t ) );
@@ -1029,7 +976,7 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16] )
{
- mbedtls_internal_aes_decrypt( ctx, input, output );
+ MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
}
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
@@ -1082,7 +1029,7 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[16];
AES_VALIDATE_RET( ctx != NULL );
@@ -1152,35 +1099,6 @@ exit:
#if defined(MBEDTLS_CIPHER_MODE_XTS)
-/* Endianess with 64 bits values */
-#ifndef GET_UINT64_LE
-#define GET_UINT64_LE(n,b,i) \
-{ \
- (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
- | ( (uint64_t) (b)[(i) + 6] << 48 ) \
- | ( (uint64_t) (b)[(i) + 5] << 40 ) \
- | ( (uint64_t) (b)[(i) + 4] << 32 ) \
- | ( (uint64_t) (b)[(i) + 3] << 24 ) \
- | ( (uint64_t) (b)[(i) + 2] << 16 ) \
- | ( (uint64_t) (b)[(i) + 1] << 8 ) \
- | ( (uint64_t) (b)[(i) ] ); \
-}
-#endif
-
-#ifndef PUT_UINT64_LE
-#define PUT_UINT64_LE(n,b,i) \
-{ \
- (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) ] = (unsigned char) ( (n) ); \
-}
-#endif
-
typedef unsigned char mbedtls_be128[16];
/*
@@ -1196,14 +1114,14 @@ static void mbedtls_gf128mul_x_ble( unsigned char r[16],
{
uint64_t a, b, ra, rb;
- GET_UINT64_LE( a, x, 0 );
- GET_UINT64_LE( b, x, 8 );
+ a = MBEDTLS_GET_UINT64_LE( x, 0 );
+ b = MBEDTLS_GET_UINT64_LE( x, 8 );
ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
rb = ( a >> 63 ) | ( b << 1 );
- PUT_UINT64_LE( ra, r, 0 );
- PUT_UINT64_LE( rb, r, 8 );
+ MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
+ MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
}
/*
@@ -1216,7 +1134,7 @@ int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t blocks = length / 16;
size_t leftover = length % 16;
unsigned char tweak[16];
@@ -1329,7 +1247,7 @@ int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
unsigned char *output )
{
int c;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
AES_VALIDATE_RET( ctx != NULL );
@@ -1397,7 +1315,7 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char c;
unsigned char ov[17];
@@ -1489,7 +1407,7 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
unsigned char *output )
{
int c, i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
AES_VALIDATE_RET( ctx != NULL );
@@ -1884,7 +1802,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( buf, 0, 16 );
@@ -1946,7 +1864,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memset( iv , 0, 16 );
@@ -2021,7 +1939,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_cfb128_iv, 16 );
@@ -2084,7 +2002,7 @@ int mbedtls_aes_self_test( int verbose )
mode = i & 1;
if( verbose != 0 )
- mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
+ mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
memcpy( iv, aes_test_ofb_iv, 16 );
diff --git a/thirdparty/mbedtls/library/aesni.c b/thirdparty/mbedtls/library/aesni.c
index 358d4ad860..996292ff6d 100644
--- a/thirdparty/mbedtls/library/aesni.c
+++ b/thirdparty/mbedtls/library/aesni.c
@@ -2,13 +2,7 @@
* AES-NI support functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -49,11 +22,7 @@
* [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_AESNI_C)
diff --git a/thirdparty/mbedtls/library/arc4.c b/thirdparty/mbedtls/library/arc4.c
index 6729bab002..b34dc5e754 100644
--- a/thirdparty/mbedtls/library/arc4.c
+++ b/thirdparty/mbedtls/library/arc4.c
@@ -2,13 +2,7 @@
* An implementation of the ARCFOUR algorithm
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ARCFOUR algorithm was publicly disclosed on 94/09.
@@ -49,11 +22,7 @@
* http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ARC4_C)
diff --git a/thirdparty/mbedtls/library/aria.c b/thirdparty/mbedtls/library/aria.c
index 50ccb91c70..bc05c4a319 100644
--- a/thirdparty/mbedtls/library/aria.c
+++ b/thirdparty/mbedtls/library/aria.c
@@ -2,13 +2,7 @@
* ARIA implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,11 +23,7 @@
* [2] https://tools.ietf.org/html/rfc5794
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ARIA_C)
@@ -87,29 +56,6 @@
MBEDTLS_INTERNAL_VALIDATE( cond )
/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE( n, b, i ) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE( n, b, i ) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
-/*
* modify byte order: ( A B C D ) -> ( B A D C ), i.e. swap pairs of bytes
*
* This is submatrix P1 in [1] Appendix B.1
@@ -266,22 +212,22 @@ static inline void aria_sl( uint32_t *a, uint32_t *b,
const uint8_t sa[256], const uint8_t sb[256],
const uint8_t sc[256], const uint8_t sd[256] )
{
- *a = ( (uint32_t) sa[ *a & 0xFF] ) ^
- (((uint32_t) sb[(*a >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*a >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *a >> 24 ]) << 24);
- *b = ( (uint32_t) sa[ *b & 0xFF] ) ^
- (((uint32_t) sb[(*b >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*b >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *b >> 24 ]) << 24);
- *c = ( (uint32_t) sa[ *c & 0xFF] ) ^
- (((uint32_t) sb[(*c >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*c >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *c >> 24 ]) << 24);
- *d = ( (uint32_t) sa[ *d & 0xFF] ) ^
- (((uint32_t) sb[(*d >> 8) & 0xFF]) << 8) ^
- (((uint32_t) sc[(*d >> 16) & 0xFF]) << 16) ^
- (((uint32_t) sd[ *d >> 24 ]) << 24);
+ *a = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *a ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *a ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *a ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *a ) ]) << 24);
+ *b = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *b ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *b ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *b ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *b ) ]) << 24);
+ *c = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *c ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *c ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *c ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *c ) ]) << 24);
+ *d = ( (uint32_t) sa[ MBEDTLS_BYTE_0( *d ) ] ) ^
+ (((uint32_t) sb[ MBEDTLS_BYTE_1( *d ) ]) << 8) ^
+ (((uint32_t) sc[ MBEDTLS_BYTE_2( *d ) ]) << 16) ^
+ (((uint32_t) sd[ MBEDTLS_BYTE_3( *d ) ]) << 24);
}
/*
@@ -439,7 +385,8 @@ static void aria_fe_xor( uint32_t r[4], const uint32_t p[4],
* Big endian 128-bit rotation: r = a ^ (b <<< n), used only in key setup.
*
* We chose to store bytes into 32-bit words in little-endian format (see
- * GET/PUT_UINT32_LE) so we need to reverse bytes here.
+ * MBEDTLS_GET_UINT32_LE / MBEDTLS_PUT_UINT32_LE ) so we need to reverse
+ * bytes here.
*/
static void aria_rot128( uint32_t r[4], const uint32_t a[4],
const uint32_t b[4], uint8_t n )
@@ -487,21 +434,21 @@ int mbedtls_aria_setkey_enc( mbedtls_aria_context *ctx,
return( MBEDTLS_ERR_ARIA_BAD_INPUT_DATA );
/* Copy key to W0 (and potential remainder to W1) */
- GET_UINT32_LE( w[0][0], key, 0 );
- GET_UINT32_LE( w[0][1], key, 4 );
- GET_UINT32_LE( w[0][2], key, 8 );
- GET_UINT32_LE( w[0][3], key, 12 );
+ w[0][0] = MBEDTLS_GET_UINT32_LE( key, 0 );
+ w[0][1] = MBEDTLS_GET_UINT32_LE( key, 4 );
+ w[0][2] = MBEDTLS_GET_UINT32_LE( key, 8 );
+ w[0][3] = MBEDTLS_GET_UINT32_LE( key, 12 );
memset( w[1], 0, 16 );
if( keybits >= 192 )
{
- GET_UINT32_LE( w[1][0], key, 16 ); // 192 bit key
- GET_UINT32_LE( w[1][1], key, 20 );
+ w[1][0] = MBEDTLS_GET_UINT32_LE( key, 16 ); // 192 bit key
+ w[1][1] = MBEDTLS_GET_UINT32_LE( key, 20 );
}
if( keybits == 256 )
{
- GET_UINT32_LE( w[1][2], key, 24 ); // 256 bit key
- GET_UINT32_LE( w[1][3], key, 28 );
+ w[1][2] = MBEDTLS_GET_UINT32_LE( key, 24 ); // 256 bit key
+ w[1][3] = MBEDTLS_GET_UINT32_LE( key, 28 );
}
i = ( keybits - 128 ) >> 6; // index: 0, 1, 2
@@ -578,10 +525,10 @@ int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
ARIA_VALIDATE_RET( input != NULL );
ARIA_VALIDATE_RET( output != NULL );
- GET_UINT32_LE( a, input, 0 );
- GET_UINT32_LE( b, input, 4 );
- GET_UINT32_LE( c, input, 8 );
- GET_UINT32_LE( d, input, 12 );
+ a = MBEDTLS_GET_UINT32_LE( input, 0 );
+ b = MBEDTLS_GET_UINT32_LE( input, 4 );
+ c = MBEDTLS_GET_UINT32_LE( input, 8 );
+ d = MBEDTLS_GET_UINT32_LE( input, 12 );
i = 0;
while( 1 )
@@ -613,10 +560,10 @@ int mbedtls_aria_crypt_ecb( mbedtls_aria_context *ctx,
c ^= ctx->rk[i][2];
d ^= ctx->rk[i][3];
- PUT_UINT32_LE( a, output, 0 );
- PUT_UINT32_LE( b, output, 4 );
- PUT_UINT32_LE( c, output, 8 );
- PUT_UINT32_LE( d, output, 12 );
+ MBEDTLS_PUT_UINT32_LE( a, output, 0 );
+ MBEDTLS_PUT_UINT32_LE( b, output, 4 );
+ MBEDTLS_PUT_UINT32_LE( c, output, 8 );
+ MBEDTLS_PUT_UINT32_LE( d, output, 12 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/asn1parse.c b/thirdparty/mbedtls/library/asn1parse.c
index 10239fdd15..22747d3ba4 100644
--- a/thirdparty/mbedtls/library/asn1parse.c
+++ b/thirdparty/mbedtls/library/asn1parse.c
@@ -2,13 +2,7 @@
* Generic ASN.1 parsing
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -149,7 +119,7 @@ int mbedtls_asn1_get_bool( unsigned char **p,
const unsigned char *end,
int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 )
@@ -164,21 +134,41 @@ int mbedtls_asn1_get_bool( unsigned char **p,
return( 0 );
}
-int mbedtls_asn1_get_int( unsigned char **p,
- const unsigned char *end,
- int *val )
+static int asn1_get_tagged_int( unsigned char **p,
+ const unsigned char *end,
+ int tag, int *val )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 )
return( ret );
- if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
+ /*
+ * len==0 is malformed (0 must be represented as 020100 for INTEGER,
+ * or 0A0100 for ENUMERATED tags
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ /* This is a cryptography library. Reject negative integers. */
+ if( ( **p & 0x80 ) != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
- *val = 0;
+ /* Skip leading zeros. */
+ while( len > 0 && **p == 0 )
+ {
+ ++( *p );
+ --len;
+ }
+ /* Reject integers that don't fit in an int. This code assumes that
+ * the int type has no padding bit. */
+ if( len > sizeof( int ) )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ if( len == sizeof( int ) && ( **p & 0x80 ) != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+
+ *val = 0;
while( len-- > 0 )
{
*val = ( *val << 8 ) | **p;
@@ -188,12 +178,26 @@ int mbedtls_asn1_get_int( unsigned char **p,
return( 0 );
}
+int mbedtls_asn1_get_int( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_INTEGER, val) );
+}
+
+int mbedtls_asn1_get_enum( unsigned char **p,
+ const unsigned char *end,
+ int *val )
+{
+ return( asn1_get_tagged_int( p, end, MBEDTLS_ASN1_ENUMERATED, val) );
+}
+
#if defined(MBEDTLS_BIGNUM_C)
int mbedtls_asn1_get_mpi( unsigned char **p,
const unsigned char *end,
mbedtls_mpi *X )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
@@ -210,7 +214,7 @@ int mbedtls_asn1_get_mpi( unsigned char **p,
int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
mbedtls_asn1_bitstring *bs)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Certificate type is a single byte bitstring */
if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
@@ -238,82 +242,145 @@ int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
}
/*
- * Get a bit string without unused bits
+ * Traverse an ASN.1 "SEQUENCE OF <tag>"
+ * and call a callback for each entry found.
*/
-int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
- size_t *len )
-{
- int ret;
-
- if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
- return( ret );
-
- if( (*len)-- < 2 || *(*p)++ != 0 )
- return( MBEDTLS_ERR_ASN1_INVALID_DATA );
-
- return( 0 );
-}
-
-
-
-/*
- * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
- */
-int mbedtls_asn1_get_sequence_of( unsigned char **p,
- const unsigned char *end,
- mbedtls_asn1_sequence *cur,
- int tag)
+int mbedtls_asn1_traverse_sequence_of(
+ unsigned char **p,
+ const unsigned char *end,
+ unsigned char tag_must_mask, unsigned char tag_must_val,
+ unsigned char tag_may_mask, unsigned char tag_may_val,
+ int (*cb)( void *ctx, int tag,
+ unsigned char *start, size_t len ),
+ void *ctx )
{
int ret;
size_t len;
- mbedtls_asn1_buf *buf;
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ {
return( ret );
+ }
if( *p + len != end )
return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
while( *p < end )
{
- buf = &(cur->buf);
- buf->tag = **p;
+ unsigned char const tag = *(*p)++;
- if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 )
- return( ret );
+ if( ( tag & tag_must_mask ) != tag_must_val )
+ return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
- buf->p = *p;
- *p += buf->len;
+ if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 )
+ return( ret );
- /* Allocate and assign next pointer */
- if( *p < end )
+ if( ( tag & tag_may_mask ) == tag_may_val )
{
- cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1,
- sizeof( mbedtls_asn1_sequence ) );
+ if( cb != NULL )
+ {
+ ret = cb( ctx, tag, *p, len );
+ if( ret != 0 )
+ return( ret );
+ }
+ }
- if( cur->next == NULL )
- return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+ *p += len;
+ }
- cur = cur->next;
- }
+ return( 0 );
+}
+
+/*
+ * Get a bit string without unused bits
+ */
+int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
+ size_t *len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 )
+ return( ret );
+
+ if( *len == 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ --( *len );
+
+ if( **p != 0 )
+ return( MBEDTLS_ERR_ASN1_INVALID_DATA );
+ ++( *p );
+
+ return( 0 );
+}
+
+void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq )
+{
+ while( seq != NULL )
+ {
+ mbedtls_asn1_sequence *next = seq->next;
+ mbedtls_platform_zeroize( seq, sizeof( *seq ) );
+ mbedtls_free( seq );
+ seq = next;
}
+}
- /* Set final sequence entry's next pointer to NULL */
- cur->next = NULL;
+typedef struct
+{
+ int tag;
+ mbedtls_asn1_sequence *cur;
+} asn1_get_sequence_of_cb_ctx_t;
+
+static int asn1_get_sequence_of_cb( void *ctx,
+ int tag,
+ unsigned char *start,
+ size_t len )
+{
+ asn1_get_sequence_of_cb_ctx_t *cb_ctx =
+ (asn1_get_sequence_of_cb_ctx_t *) ctx;
+ mbedtls_asn1_sequence *cur =
+ cb_ctx->cur;
- if( *p != end )
- return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ if( cur->buf.p != NULL )
+ {
+ cur->next =
+ mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+ if( cur->next == NULL )
+ return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+
+ cur = cur->next;
+ }
+ cur->buf.p = start;
+ cur->buf.len = len;
+ cur->buf.tag = tag;
+
+ cb_ctx->cur = cur;
return( 0 );
}
+/*
+ * Parses and splits an ASN.1 "SEQUENCE OF <tag>"
+ */
+int mbedtls_asn1_get_sequence_of( unsigned char **p,
+ const unsigned char *end,
+ mbedtls_asn1_sequence *cur,
+ int tag)
+{
+ asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
+ memset( cur, 0, sizeof( mbedtls_asn1_sequence ) );
+ return( mbedtls_asn1_traverse_sequence_of(
+ p, end, 0xFF, tag, 0, 0,
+ asn1_get_sequence_of_cb, &cb_ctx ) );
+}
+
int mbedtls_asn1_get_alg( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
@@ -357,7 +424,7 @@ int mbedtls_asn1_get_alg_null( unsigned char **p,
const unsigned char *end,
mbedtls_asn1_buf *alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf params;
memset( &params, 0, sizeof(mbedtls_asn1_buf) );
diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c
index d94d0a7605..3811ef27a3 100644
--- a/thirdparty/mbedtls/library/asn1write.c
+++ b/thirdparty/mbedtls/library/asn1write.c
@@ -2,13 +2,7 @@
* ASN.1 buffer writing functionality
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ASN1_WRITE_C)
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -90,8 +60,8 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 3 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
*--(*p) = 0x82;
return( 3 );
}
@@ -101,9 +71,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 4 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
- *--(*p) = ( len >> 16 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
+ *--(*p) = MBEDTLS_BYTE_2( len );
*--(*p) = 0x83;
return( 4 );
}
@@ -115,10 +85,10 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
if( *p - start < 5 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
- *--(*p) = ( len ) & 0xFF;
- *--(*p) = ( len >> 8 ) & 0xFF;
- *--(*p) = ( len >> 16 ) & 0xFF;
- *--(*p) = ( len >> 24 ) & 0xFF;
+ *--(*p) = MBEDTLS_BYTE_0( len );
+ *--(*p) = MBEDTLS_BYTE_1( len );
+ *--(*p) = MBEDTLS_BYTE_2( len );
+ *--(*p) = MBEDTLS_BYTE_3( len );
*--(*p) = 0x84;
return( 5 );
}
@@ -156,7 +126,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
#if defined(MBEDTLS_BIGNUM_C)
int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
// Write the MPI
@@ -193,7 +163,7 @@ cleanup:
int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
// Write NULL
@@ -207,7 +177,7 @@ int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start )
int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
@@ -222,7 +192,7 @@ int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *s
const char *oid, size_t oid_len,
size_t par_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( par_len == 0 )
@@ -241,7 +211,7 @@ int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *s
int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( *p - start < 1 )
@@ -256,36 +226,49 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolea
return( (int) len );
}
-int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
+static int asn1_write_tagged_int( unsigned char **p, unsigned char *start, int val, int tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
- if( *p - start < 1 )
- return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
-
- len += 1;
- *--(*p) = val;
-
- if( val > 0 && **p & 0x80 )
+ do
{
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+ len += 1;
+ *--(*p) = val & 0xff;
+ val >>= 8;
+ }
+ while( val > 0 );
+ if( **p & 0x80 )
+ {
+ if( *p - start < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0x00;
len += 1;
}
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_INTEGER ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, tag ) );
return( (int) len );
}
+int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val )
+{
+ return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_INTEGER ) );
+}
+
+int mbedtls_asn1_write_enum( unsigned char **p, unsigned char *start, int val )
+{
+ return( asn1_write_tagged_int( p, start, val, MBEDTLS_ASN1_ENUMERATED ) );
+}
+
int mbedtls_asn1_write_tagged_string( unsigned char **p, unsigned char *start, int tag,
const char *text, size_t text_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
@@ -315,10 +298,53 @@ int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start,
return( mbedtls_asn1_write_tagged_string(p, start, MBEDTLS_ASN1_IA5_STRING, text, text_len) );
}
+int mbedtls_asn1_write_named_bitstring( unsigned char **p,
+ unsigned char *start,
+ const unsigned char *buf,
+ size_t bits )
+{
+ size_t unused_bits, byte_len;
+ const unsigned char *cur_byte;
+ unsigned char cur_byte_shifted;
+ unsigned char bit;
+
+ byte_len = ( bits + 7 ) / 8;
+ unused_bits = ( byte_len * 8 ) - bits;
+
+ /*
+ * Named bitstrings require that trailing 0s are excluded in the encoding
+ * of the bitstring. Trailing 0s are considered part of the 'unused' bits
+ * when encoding this value in the first content octet
+ */
+ if( bits != 0 )
+ {
+ cur_byte = buf + byte_len - 1;
+ cur_byte_shifted = *cur_byte >> unused_bits;
+
+ for( ; ; )
+ {
+ bit = cur_byte_shifted & 0x1;
+ cur_byte_shifted >>= 1;
+
+ if( bit != 0 )
+ break;
+
+ bits--;
+ if( bits == 0 )
+ break;
+
+ if( bits % 8 == 0 )
+ cur_byte_shifted = *--cur_byte;
+ }
+ }
+
+ return( mbedtls_asn1_write_bitstring( p, start, buf, bits ) );
+}
+
int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t bits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
size_t unused_bits, byte_len;
@@ -351,7 +377,7 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start,
const unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) );
@@ -411,18 +437,26 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(
memcpy( cur->oid.p, oid, oid_len );
cur->val.len = val_len;
- cur->val.p = mbedtls_calloc( 1, val_len );
- if( cur->val.p == NULL )
+ if( val_len != 0 )
{
- mbedtls_free( cur->oid.p );
- mbedtls_free( cur );
- return( NULL );
+ cur->val.p = mbedtls_calloc( 1, val_len );
+ if( cur->val.p == NULL )
+ {
+ mbedtls_free( cur->oid.p );
+ mbedtls_free( cur );
+ return( NULL );
+ }
}
cur->next = *head;
*head = cur;
}
- else if( cur->val.len < val_len )
+ else if( val_len == 0 )
+ {
+ mbedtls_free( cur->val.p );
+ cur->val.p = NULL;
+ }
+ else if( cur->val.len != val_len )
{
/*
* Enlarge existing value buffer if needed
diff --git a/thirdparty/mbedtls/library/base64.c b/thirdparty/mbedtls/library/base64.c
index b1bd330ddd..83daa0bcc6 100644
--- a/thirdparty/mbedtls/library/base64.c
+++ b/thirdparty/mbedtls/library/base64.c
@@ -2,13 +2,7 @@
* RFC 1521 base64 encoding/decoding
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BASE64_C)
#include "mbedtls/base64.h"
+#include "constant_time_internal.h"
#include <stdint.h>
@@ -68,38 +38,6 @@
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
-/* Return 0xff if low <= c <= high, 0 otherwise.
- *
- * Constant flow with respect to c.
- */
-static unsigned char mask_of_range( unsigned char low, unsigned char high,
- unsigned char c )
-{
- /* low_mask is: 0 if low <= c, 0x...ff if low > c */
- unsigned low_mask = ( (unsigned) c - low ) >> 8;
- /* high_mask is: 0 if c <= high, 0x...ff if c > high */
- unsigned high_mask = ( (unsigned) high - c ) >> 8;
- return( ~( low_mask | high_mask ) & 0xff );
-}
-
-/* Given a value in the range 0..63, return the corresponding Base64 digit.
- * The implementation assumes that letters are consecutive (e.g. ASCII
- * but not EBCDIC).
- */
-static unsigned char enc_char( unsigned char val )
-{
- unsigned char digit = 0;
- /* For each range of values, if val is in that range, mask digit with
- * the corresponding value. Since val can only be in a single range,
- * only at most one masking will change digit. */
- digit |= mask_of_range( 0, 25, val ) & ( 'A' + val );
- digit |= mask_of_range( 26, 51, val ) & ( 'a' + val - 26 );
- digit |= mask_of_range( 52, 61, val ) & ( '0' + val - 52 );
- digit |= mask_of_range( 62, 62, val ) & '+';
- digit |= mask_of_range( 63, 63, val ) & '/';
- return( digit );
-}
-
/*
* Encode a buffer into base64 format
*/
@@ -140,10 +78,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C2 = *src++;
C3 = *src++;
- *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
- *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
- *p++ = enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) ) & 0x3F );
- *p++ = enc_char( C3 & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+ & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C2 & 15 ) << 2 ) + ( C3 >> 6 ) )
+ & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( C3 & 0x3F );
}
if( i < slen )
@@ -151,11 +91,12 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
C1 = *src++;
C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
- *p++ = enc_char( ( C1 >> 2 ) & 0x3F );
- *p++ = enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( C1 >> 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( ( C1 & 3 ) << 4 ) + ( C2 >> 4 ) )
+ & 0x3F );
if( ( i + 1 ) < slen )
- *p++ = enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
+ *p++ = mbedtls_ct_base64_enc_char( ( ( C2 & 15 ) << 2 ) & 0x3F );
else *p++ = '=';
*p++ = '=';
@@ -167,34 +108,6 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
return( 0 );
}
-/* Given a Base64 digit, return its value.
- * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
- * return -1.
- *
- * The implementation assumes that letters are consecutive (e.g. ASCII
- * but not EBCDIC).
- *
- * The implementation is constant-flow (no branch or memory access depending
- * on the value of c) unless the compiler inlines and optimizes a specific
- * access.
- */
-static signed char dec_value( unsigned char c )
-{
- unsigned char val = 0;
- /* For each range of digits, if c is in that range, mask val with
- * the corresponding value. Since c can only be in a single range,
- * only at most one masking will change val. Set val to one plus
- * the desired value so that it stays 0 if c is in none of the ranges. */
- val |= mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 );
- val |= mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
- val |= mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
- val |= mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
- val |= mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
- /* At this point, val is 0 if c is an invalid digit and v+1 if c is
- * a digit with the value v. */
- return( val - 1 );
-}
-
/*
* Decode a base64-formatted buffer
*/
@@ -247,7 +160,7 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
{
if( equals != 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
- if( dec_value( src[i] ) < 0 )
+ if( mbedtls_ct_base64_dec_value( src[i] ) < 0 )
return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER );
}
n++;
@@ -282,14 +195,14 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
if( *src == '=' )
++equals;
else
- x |= dec_value( *src );
+ x |= mbedtls_ct_base64_dec_value( *src );
if( ++accumulated_digits == 4 )
{
accumulated_digits = 0;
- *p++ = (unsigned char)( x >> 16 );
- if( equals <= 1 ) *p++ = (unsigned char)( x >> 8 );
- if( equals <= 0 ) *p++ = (unsigned char)( x );
+ *p++ = MBEDTLS_BYTE_2( x );
+ if( equals <= 1 ) *p++ = MBEDTLS_BYTE_1( x );
+ if( equals <= 0 ) *p++ = MBEDTLS_BYTE_0( x );
}
}
diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c
index c553d0c5af..62e7f76727 100644
--- a/thirdparty/mbedtls/library/bignum.c
+++ b/thirdparty/mbedtls/library/bignum.c
@@ -2,13 +2,7 @@
* Multi-precision integer library
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -60,17 +33,15 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BIGNUM_C)
#include "mbedtls/bignum.h"
#include "mbedtls/bn_mul.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "constant_time_internal.h"
#include <limits.h>
#include <string.h>
@@ -212,8 +183,35 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
return( 0 );
}
+/* Resize X to have exactly n limbs and set it to 0. */
+static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
+{
+ if( limbs == 0 )
+ {
+ mbedtls_mpi_free( X );
+ return( 0 );
+ }
+ else if( X->n == limbs )
+ {
+ memset( X->p, 0, limbs * ciL );
+ X->s = 1;
+ return( 0 );
+ }
+ else
+ {
+ mbedtls_mpi_free( X );
+ return( mbedtls_mpi_grow( X, limbs ) );
+ }
+}
+
/*
- * Copy the contents of Y into X
+ * Copy the contents of Y into X.
+ *
+ * This function is not constant-time. Leading zeros in Y may be removed.
+ *
+ * Ensure that X does not shrink. This is not guaranteed by the public API,
+ * but some code in the bignum module relies on this property, for example
+ * in mbedtls_mpi_exp_mod().
*/
int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
{
@@ -227,7 +225,11 @@ int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
if( Y->n == 0 )
{
- mbedtls_mpi_free( X );
+ if( X->n != 0 )
+ {
+ X->s = 1;
+ memset( X->p, 0, X->n * ciL );
+ }
return( 0 );
}
@@ -268,168 +270,12 @@ void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
memcpy( Y, &T, sizeof( mbedtls_mpi ) );
}
-/**
- * Select between two sign values in constant-time.
- *
- * This is functionally equivalent to second ? a : b but uses only bit
- * operations in order to avoid branches.
- *
- * \param[in] a The first sign; must be either +1 or -1.
- * \param[in] b The second sign; must be either +1 or -1.
- * \param[in] second Must be either 1 (return b) or 0 (return a).
- *
- * \return The selected sign value.
- */
-static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
-{
- /* In order to avoid questions about what we can reasonnably assume about
- * the representations of signed integers, move everything to unsigned
- * by taking advantage of the fact that a and b are either +1 or -1. */
- unsigned ua = a + 1;
- unsigned ub = b + 1;
-
- /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
- const unsigned mask = second << 1;
-
- /* select ua or ub */
- unsigned ur = ( ua & ~mask ) | ( ub & mask );
-
- /* ur is now 0 or 2, convert back to -1 or +1 */
- return( (int) ur - 1 );
-}
-
-/*
- * Conditionally assign dest = src, without leaking information
- * about whether the assignment was made or not.
- * dest and src must be arrays of limbs of size n.
- * assign must be 0 or 1.
- */
-static void mpi_safe_cond_assign( size_t n,
- mbedtls_mpi_uint *dest,
- const mbedtls_mpi_uint *src,
- unsigned char assign )
-{
- size_t i;
-
- /* 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
-
- /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
- const mbedtls_mpi_uint mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- for( i = 0; i < n; i++ )
- dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
-}
-
-/*
- * Conditionally assign X = Y, without leaking information
- * about whether the assignment was made or not.
- * (Leaking information about the respective sizes of X and Y is ok however.)
- */
-int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
-{
- int ret = 0;
- size_t i;
- mbedtls_mpi_uint limb_mask;
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
-
- /* 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
-
- /* make sure assign is 0 or 1 in a time-constant manner */
- assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
- /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
- limb_mask = -assign;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
-
- X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
-
- mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
-
- for( i = Y->n; i < X->n; i++ )
- X->p[i] &= ~limb_mask;
-
-cleanup:
- return( ret );
-}
-
-/*
- * Conditionally swap X and Y, without leaking information
- * about whether the swap was made or not.
- * Here it is not ok to simply swap the pointers, which whould lead to
- * different memory access patterns when X and Y are used afterwards.
- */
-int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
-{
- int ret, s;
- size_t i;
- mbedtls_mpi_uint limb_mask;
- mbedtls_mpi_uint tmp;
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
-
- if( X == Y )
- return( 0 );
-
- /* 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
-
- /* make sure swap is 0 or 1 in a time-constant manner */
- swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
- /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
- limb_mask = -swap;
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
-
- s = X->s;
- X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
- Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
-
-
- for( i = 0; i < X->n; i++ )
- {
- tmp = X->p[i];
- X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
- Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
- }
-
-cleanup:
- return( ret );
-}
-
/*
* Set value from integer
*/
int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET( X != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
@@ -572,7 +418,7 @@ static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
*/
int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j, slen, n;
int sign = 1;
mbedtls_mpi_uint d;
@@ -585,6 +431,12 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
mbedtls_mpi_init( &T );
+ if( s[0] == 0 )
+ {
+ mbedtls_mpi_free( X );
+ return( 0 );
+ }
+
if( s[0] == '-' )
{
++s;
@@ -637,7 +489,7 @@ cleanup:
static int mpi_write_hlp( mbedtls_mpi *X, int radix,
char **p, const size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_uint r;
size_t length = 0;
char *p_end = *p + buflen;
@@ -802,7 +654,7 @@ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
*/
int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n, slen, plen;
/*
* Buffer should have space for (short) label and decimal formatted MPI,
@@ -932,11 +784,37 @@ static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
}
/*
+ * Import X from unsigned binary data, little endian
+ */
+int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i;
+ size_t const limbs = CHARS_TO_LIMBS( buflen );
+
+ /* Ensure that target MPI has exactly the necessary number of limbs */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
+
+ for( i = 0; i < buflen; i++ )
+ X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
+
+cleanup:
+
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
+ return( ret );
+}
+
+/*
* Import X from unsigned binary data, big endian
*/
int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t const limbs = CHARS_TO_LIMBS( buflen );
size_t const overhead = ( limbs * ciL ) - buflen;
unsigned char *Xp;
@@ -945,17 +823,11 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
/* Ensure that target MPI has exactly the necessary number of limbs */
- if( X->n != limbs )
- {
- mbedtls_mpi_free( X );
- mbedtls_mpi_init( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
- /* Avoid calling `memcpy` with NULL source argument,
+ /* Avoid calling `memcpy` with NULL source or destination argument,
* even if buflen is 0. */
- if( buf != NULL )
+ if( buflen != 0 )
{
Xp = (unsigned char*) X->p;
memcpy( Xp + overhead, buf, buflen );
@@ -965,10 +837,54 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu
cleanup:
+ /*
+ * This function is also used to import keys. However, wiping the buffers
+ * upon failure is not necessary because failure only can happen before any
+ * input is copied.
+ */
return( ret );
}
/*
+ * Export X into unsigned binary data, little endian
+ */
+int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
+ unsigned char *buf, size_t buflen )
+{
+ size_t stored_bytes = X->n * ciL;
+ size_t bytes_to_copy;
+ size_t i;
+
+ if( stored_bytes < buflen )
+ {
+ bytes_to_copy = stored_bytes;
+ }
+ else
+ {
+ bytes_to_copy = buflen;
+
+ /* The output buffer is smaller than the allocated size of X.
+ * However X may fit if its leading bytes are zero. */
+ for( i = bytes_to_copy; i < stored_bytes; i++ )
+ {
+ if( GET_BYTE( X, i ) != 0 )
+ return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+ }
+
+ for( i = 0; i < bytes_to_copy; i++ )
+ buf[i] = GET_BYTE( X, i );
+
+ if( stored_bytes < buflen )
+ {
+ /* Write trailing 0 bytes */
+ memset( buf + stored_bytes, 0, buflen - stored_bytes );
+ }
+
+ return( 0 );
+}
+
+/*
* Export X into unsigned binary data, big endian
*/
int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
@@ -1019,7 +935,7 @@ int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
*/
int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, v0, t1;
mbedtls_mpi_uint r0 = 0, r1;
MPI_VALIDATE_RET( X != NULL );
@@ -1176,107 +1092,6 @@ int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
return( 0 );
}
-/** Decide if an integer is less than the other, without branches.
- *
- * \param x First integer.
- * \param y Second integer.
- *
- * \return 1 if \p x is less than \p y, 0 otherwise
- */
-static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
- const mbedtls_mpi_uint y )
-{
- mbedtls_mpi_uint ret;
- mbedtls_mpi_uint cond;
-
- /*
- * Check if the most significant bits (MSB) of the operands are different.
- */
- cond = ( x ^ y );
- /*
- * If the MSB are the same then the difference x-y will be negative (and
- * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
- */
- ret = ( x - y ) & ~cond;
- /*
- * If the MSB are different, then the operand with the MSB of 1 is the
- * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
- * the MSB of y is 0.)
- */
- ret |= y & cond;
-
-
- ret = ret >> ( biL - 1 );
-
- return (unsigned) ret;
-}
-
-/*
- * Compare signed values in constant time
- */
-int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
- unsigned *ret )
-{
- size_t i;
- /* The value of any of these variables is either 0 or 1 at all times. */
- unsigned cond, done, X_is_negative, Y_is_negative;
-
- MPI_VALIDATE_RET( X != NULL );
- MPI_VALIDATE_RET( Y != NULL );
- MPI_VALIDATE_RET( ret != NULL );
-
- if( X->n != Y->n )
- return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
-
- /*
- * Set sign_N to 1 if N >= 0, 0 if N < 0.
- * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
- */
- X_is_negative = ( X->s & 2 ) >> 1;
- Y_is_negative = ( Y->s & 2 ) >> 1;
-
- /*
- * If the signs are different, then the positive operand is the bigger.
- * That is if X is negative (X_is_negative == 1), then X < Y is true and it
- * is false if X is positive (X_is_negative == 0).
- */
- cond = ( X_is_negative ^ Y_is_negative );
- *ret = cond & X_is_negative;
-
- /*
- * This is a constant-time function. We might have the result, but we still
- * need to go through the loop. Record if we have the result already.
- */
- done = cond;
-
- for( i = X->n; i > 0; i-- )
- {
- /*
- * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
- * X and Y are negative.
- *
- * Again even if we can make a decision, we just mark the result and
- * the fact that we are done and continue looping.
- */
- cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
- *ret |= cond & ( 1 - done ) & X_is_negative;
- done |= cond;
-
- /*
- * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
- * X and Y are positive.
- *
- * Again even if we can make a decision, we just mark the result and
- * the fact that we are done and continue looping.
- */
- cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
- *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
- done |= cond;
- }
-
- return( 0 );
-}
-
/*
* Compare signed values
*/
@@ -1299,7 +1114,7 @@ int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
*/
int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j;
mbedtls_mpi_uint *o, *p, c, tmp;
MPI_VALIDATE_RET( X != NULL );
@@ -1356,29 +1171,32 @@ cleanup:
/**
* Helper for mbedtls_mpi subtraction.
*
- * Calculate d - s where d and s have the same size.
+ * Calculate l - r where l and r have the same size.
* This function operates modulo (2^ciL)^n and returns the carry
- * (1 if there was a wraparound, i.e. if `d < s`, and 0 otherwise).
+ * (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
*
- * \param n Number of limbs of \p d and \p s.
- * \param[in,out] d On input, the left operand.
- * On output, the result of the subtraction:
- * \param[in] s The right operand.
+ * d may be aliased to l or r.
*
- * \return 1 if `d < s`.
- * 0 if `d >= s`.
+ * \param n Number of limbs of \p d, \p l and \p r.
+ * \param[out] d The result of the subtraction.
+ * \param[in] l The left operand.
+ * \param[in] r The right operand.
+ *
+ * \return 1 if `l < r`.
+ * 0 if `l >= r`.
*/
static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
mbedtls_mpi_uint *d,
- const mbedtls_mpi_uint *s )
+ const mbedtls_mpi_uint *l,
+ const mbedtls_mpi_uint *r )
{
size_t i;
- mbedtls_mpi_uint c, z;
+ mbedtls_mpi_uint c = 0, t, z;
- for( i = c = 0; i < n; i++, s++, d++ )
+ for( i = 0; i < n; i++ )
{
- z = ( *d < c ); *d -= c;
- c = ( *d < *s ) + z; *d -= *s;
+ z = ( l[i] < c ); t = l[i] - c;
+ c = ( t < r[i] ) + z; d[i] = t - r[i];
}
return( c );
@@ -1389,32 +1207,13 @@ static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
*/
int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- mbedtls_mpi TB;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
mbedtls_mpi_uint carry;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
- mbedtls_mpi_init( &TB );
-
- if( X == B )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
- B = &TB;
- }
-
- if( X != A )
- MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
-
- /*
- * X should always be positive as a result of unsigned subtractions.
- */
- X->s = 1;
-
- ret = 0;
-
for( n = B->n; n > 0; n-- )
if( B->p[n - 1] != 0 )
break;
@@ -1425,7 +1224,17 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
goto cleanup;
}
- carry = mpi_sub_hlp( n, X->p, B->p );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, A->n ) );
+
+ /* Set the high limbs of X to match A. Don't touch the lower limbs
+ * because X might be aliased to B, and we must not overwrite the
+ * significant digits of B. */
+ if( A->n > n )
+ memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );
+ if( X->n > A->n )
+ memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
+
+ carry = mpi_sub_hlp( n, X->p, A->p, B->p );
if( carry != 0 )
{
/* Propagate the carry to the first nonzero limb of X. */
@@ -1441,10 +1250,10 @@ int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
--X->p[n];
}
-cleanup:
-
- mbedtls_mpi_free( &TB );
+ /* X should always be positive as a result of unsigned subtractions. */
+ X->s = 1;
+cleanup:
return( ret );
}
@@ -1554,8 +1363,21 @@ int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint
return( mbedtls_mpi_sub_mpi( X, A, &B ) );
}
-/*
- * Helper for mbedtls_mpi multiplication
+/** Helper for mbedtls_mpi multiplication.
+ *
+ * Add \p b * \p s to \p d.
+ *
+ * \param i The number of limbs of \p s.
+ * \param[in] s A bignum to multiply, of size \p i.
+ * It may overlap with \p d, but only if
+ * \p d <= \p s.
+ * Its leading limb must not be \c 0.
+ * \param[in,out] d The bignum to add to.
+ * It must be sufficiently large to store the
+ * result of the multiplication. This means
+ * \p i + 1 limbs if \p d[\p i - 1] started as 0 and \p b
+ * is not known a priori.
+ * \param b A scalar to multiply.
*/
static
#if defined(__APPLE__) && defined(__arm__)
@@ -1565,7 +1387,10 @@ static
*/
__attribute__ ((noinline))
#endif
-void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
+void mpi_mul_hlp( size_t i,
+ const mbedtls_mpi_uint *s,
+ mbedtls_mpi_uint *d,
+ mbedtls_mpi_uint b )
{
mbedtls_mpi_uint c = 0, t = 0;
@@ -1620,10 +1445,10 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
t++;
- do {
+ while( c != 0 )
+ {
*d += c; c = ( *d < c ); d++;
}
- while( c != 0 );
}
/*
@@ -1631,7 +1456,7 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mp
*/
int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, j;
mbedtls_mpi TA, TB;
int result_is_zero = 0;
@@ -1683,17 +1508,37 @@ cleanup:
*/
int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
{
- mbedtls_mpi B;
- mbedtls_mpi_uint p[1];
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
- B.s = 1;
- B.n = 1;
- B.p = p;
- p[0] = b;
+ /* mpi_mul_hlp can't deal with a leading 0. */
+ size_t n = A->n;
+ while( n > 0 && A->p[n - 1] == 0 )
+ --n;
+
+ /* The general method below doesn't work if n==0 or b==0. By chance
+ * calculating the result is trivial in those cases. */
+ if( b == 0 || n == 0 )
+ {
+ return( mbedtls_mpi_lset( X, 0 ) );
+ }
- return( mbedtls_mpi_mul_mpi( X, A, &B ) );
+ /* Calculate A*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* In general, A * b requires 1 limb more than b. If
+ * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
+ * number of limbs as A and the call to grow() is not required since
+ * copy() will take care of the growth if needed. However, experimentally,
+ * making the call to grow() unconditional causes slightly fewer
+ * calls to calloc() in ECP code, presumably because it reuses the
+ * same mpi for a while and this way the mpi is more likely to directly
+ * grow to its final size. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
+ mpi_mul_hlp( n, A->p, X->p, b - 1 );
+
+cleanup:
+ return( ret );
}
/*
@@ -1798,9 +1643,10 @@ static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, t, k;
mbedtls_mpi X, Y, Z, T1, T2;
+ mbedtls_mpi_uint TP2[3];
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
@@ -1808,7 +1654,17 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
+ mbedtls_mpi_init( &T1 );
+ /*
+ * Avoid dynamic memory allocations for constant-size T2.
+ *
+ * T2 is used for comparison only and the 3 limbs are assigned explicitly,
+ * so nobody increase the size of the MPI and we're safe to use an on-stack
+ * buffer.
+ */
+ T2.s = 1;
+ T2.n = sizeof( TP2 ) / sizeof( *TP2 );
+ T2.p = TP2;
if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
{
@@ -1823,8 +1679,7 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, A->n + 2 ) );
k = mbedtls_mpi_bitlen( &Y ) % biL;
if( k < biL - 1 )
@@ -1856,6 +1711,10 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
Y.p[t], NULL);
}
+ T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
+ T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
+ T2.p[2] = X.p[i];
+
Z.p[i - t - 1]++;
do
{
@@ -1865,11 +1724,6 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
T1.p[1] = Y.p[t];
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
- T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
- T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
- T2.p[2] = X.p[i];
}
while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
@@ -1905,7 +1759,8 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
cleanup:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
- mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
+ mbedtls_mpi_free( &T1 );
+ mbedtls_platform_zeroize( TP2, sizeof( TP2 ) );
return( ret );
}
@@ -1934,7 +1789,7 @@ int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
*/
int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MPI_VALIDATE_RET( R != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
@@ -2090,14 +1945,14 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
* do the calculation without using conditional tests. */
/* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
d[n] += 1;
- d[n] -= mpi_sub_hlp( n, d, N->p );
+ d[n] -= mpi_sub_hlp( n, d, d, N->p );
/* If d0 < N then d < (2^biL)^n
* so d[n] == 0 and we want to keep A as it is.
* If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
* so d[n] == 1 and we want to set A to the result of the subtraction
* which is d - (2^biL)^n, i.e. the n least significant limbs of d.
* This exactly corresponds to a conditional assignment. */
- mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
+ mbedtls_ct_mpi_uint_cond_assign( n, A->p, d, (unsigned char) d[n] );
}
/*
@@ -2117,42 +1972,6 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
mpi_montmul( A, &U, N, mm, T );
}
-/*
- * Constant-flow boolean "equal" comparison:
- * return x == y
- *
- * This function can be used to write constant-time code by replacing branches
- * with bit operations - it can be used in conjunction with
- * mbedtls_ssl_cf_mask_from_bit().
- *
- * This function is implemented without using comparison operators, as those
- * might be translated to branches by some compilers on some platforms.
- */
-static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
-{
- /* diff = 0 if x == y, non-zero otherwise */
- const size_t diff = x ^ y;
-
- /* 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 x != y */
- const size_t diff_msb = ( diff | (size_t) -diff );
-
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-
- /* diff1 = (x != y) ? 1 : 0 */
- const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
-
- return( 1 ^ diff1 );
-}
-
/**
* Select an MPI from a table without leaking the index.
*
@@ -2170,13 +1989,12 @@ static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
*/
static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
{
- int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- for( i = 0; i < T_size; i++ )
+ for( size_t i = 0; i < T_size; i++ )
{
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
- (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
+ (unsigned char) mbedtls_ct_size_bool_eq( i, idx ) ) );
}
cleanup:
@@ -2190,7 +2008,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
const mbedtls_mpi *E, const mbedtls_mpi *N,
mbedtls_mpi *prec_RR )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t wbits, wsize, one = 1;
size_t i, j, nblimbs;
size_t bufsize, nbits;
@@ -2272,14 +2090,18 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
* W[1] = A * R^2 * R^-1 mod N = A * R mod N
*/
if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
+ {
MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
+ /* This should be a no-op because W[1] is already that large before
+ * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
+ * in mpi_montmul() below, so let's make sure. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
+ }
else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
- /* Re-grow W[1] if necessary. This should be only necessary in one corner
- * case: when A == 0 represented with A.n == 0, mbedtls_mpi_copy shrinks
- * W[1] to 0 limbs. */
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n +1 ) );
+ /* Note that this is safe because W[1] always has at least N->n limbs
+ * (it grew above and was preserved by mbedtls_mpi_copy()). */
mpi_montmul( &W[1], &RR, N, mm, &T );
/*
@@ -2421,15 +2243,15 @@ cleanup:
*/
int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t lz, lzt;
- mbedtls_mpi TG, TA, TB;
+ mbedtls_mpi TA, TB;
MPI_VALIDATE_RET( G != NULL );
MPI_VALIDATE_RET( A != NULL );
MPI_VALIDATE_RET( B != NULL );
- mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
+ mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
@@ -2450,9 +2272,6 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
if( lzt < lz )
lz = lzt;
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
-
TA.s = TB.s = 1;
/* We mostly follow the procedure described in HAC 14.54, but with some
@@ -2476,7 +2295,7 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
* Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
* and gcd(A',B') is odd or 0.
*
- * At the beginning, we have TA = |A|/2^a and TB = |B|/2^b.
+ * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
* The code maintains the following invariant:
* gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
*/
@@ -2528,8 +2347,35 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B
cleanup:
- mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
+ mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
+
+ return( ret );
+}
+
+/* Fill X with n_bytes random bytes.
+ * X must already have room for those bytes.
+ * The ordering of the bytes returned from the RNG is suitable for
+ * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
+ * The size and sign of X are unchanged.
+ * n_bytes must not be 0.
+ */
+static int mpi_fill_random_internal(
+ mbedtls_mpi *X, size_t n_bytes,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const size_t limbs = CHARS_TO_LIMBS( n_bytes );
+ const size_t overhead = ( limbs * ciL ) - n_bytes;
+
+ if( X->n < limbs )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+ memset( X->p, 0, overhead );
+ memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
+ MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
+ mpi_bigendian_to_host( X->p, limbs );
+cleanup:
return( ret );
}
@@ -2544,29 +2390,95 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t const limbs = CHARS_TO_LIMBS( size );
- size_t const overhead = ( limbs * ciL ) - size;
- unsigned char *Xp;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( f_rng != NULL );
/* Ensure that target MPI has exactly the necessary number of limbs */
- if( X->n != limbs )
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
+ if( size == 0 )
+ return( 0 );
+
+ ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
+
+cleanup:
+ return( ret );
+}
+
+int mbedtls_mpi_random( mbedtls_mpi *X,
+ mbedtls_mpi_sint min,
+ const mbedtls_mpi *N,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+ int count;
+ unsigned lt_lower = 1, lt_upper = 0;
+ size_t n_bits = mbedtls_mpi_bitlen( N );
+ size_t n_bytes = ( n_bits + 7 ) / 8;
+ mbedtls_mpi lower_bound;
+
+ if( min < 0 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+ if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
+ return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+
+ /*
+ * When min == 0, each try has at worst a probability 1/2 of failing
+ * (the msb has a probability 1/2 of being 0, and then the result will
+ * be < N), so after 30 tries failure probability is a most 2**(-30).
+ *
+ * When N is just below a power of 2, as is the case when generating
+ * a random scalar on most elliptic curves, 1 try is enough with
+ * overwhelming probability. When N is just above a power of 2,
+ * as when generating a random scalar on secp224k1, each try has
+ * a probability of failing that is almost 1/2.
+ *
+ * The probabilities are almost the same if min is nonzero but negligible
+ * compared to N. This is always the case when N is crypto-sized, but
+ * it's convenient to support small N for testing purposes. When N
+ * is small, use a higher repeat count, otherwise the probability of
+ * failure is macroscopic.
+ */
+ count = ( n_bytes > 4 ? 30 : 250 );
+
+ mbedtls_mpi_init( &lower_bound );
+
+ /* Ensure that target MPI has exactly the same number of limbs
+ * as the upper bound, even if the upper bound has leading zeros.
+ * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
+
+ /*
+ * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
+ * when f_rng is a suitably parametrized instance of HMAC_DRBG:
+ * - use the same byte ordering;
+ * - keep the leftmost n_bits bits of the generated octet string;
+ * - try until result is in the desired range.
+ * This also avoids any bias, which is especially important for ECDSA.
+ */
+ do
{
- mbedtls_mpi_free( X );
- mbedtls_mpi_init( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
- }
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
+ MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
- Xp = (unsigned char*) X->p;
- MBEDTLS_MPI_CHK( f_rng( p_rng, Xp + overhead, size ) );
+ if( --count == 0 )
+ {
+ ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+ goto cleanup;
+ }
- mpi_bigendian_to_host( X->p, limbs );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
+ }
+ while( lt_lower != 0 || lt_upper == 0 );
cleanup:
+ mbedtls_mpi_free( &lower_bound );
return( ret );
}
@@ -2575,7 +2487,7 @@ cleanup:
*/
int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( A != NULL );
@@ -2828,7 +2740,7 @@ int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi XX;
MPI_VALIDATE_RET( X != NULL );
MPI_VALIDATE_RET( f_rng != NULL );
@@ -3165,7 +3077,7 @@ int mbedtls_mpi_self_test( int verbose )
cleanup:
if( ret != 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+ mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
diff --git a/thirdparty/mbedtls/library/blowfish.c b/thirdparty/mbedtls/library/blowfish.c
index a3f9be959f..621e9f76cd 100644
--- a/thirdparty/mbedtls/library/blowfish.c
+++ b/thirdparty/mbedtls/library/blowfish.c
@@ -2,13 +2,7 @@
* Blowfish implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The Blowfish block cipher was designed by Bruce Schneier in 1993.
@@ -50,11 +23,7 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_BLOWFISH_C)
@@ -71,29 +40,6 @@
#define BLOWFISH_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = {
0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L,
0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L,
@@ -110,13 +56,13 @@ static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x )
unsigned short a, b, c, d;
uint32_t y;
- d = (unsigned short)(x & 0xFF);
+ d = MBEDTLS_BYTE_0( x );
x >>= 8;
- c = (unsigned short)(x & 0xFF);
+ c = MBEDTLS_BYTE_0( x );
x >>= 8;
- b = (unsigned short)(x & 0xFF);
+ b = MBEDTLS_BYTE_0( x );
x >>= 8;
- a = (unsigned short)(x & 0xFF);
+ a = MBEDTLS_BYTE_0( x );
y = ctx->S[0][a] + ctx->S[1][b];
y = y ^ ctx->S[2][c];
y = y + ctx->S[3][d];
@@ -273,8 +219,8 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
BLOWFISH_VALIDATE_RET( input != NULL );
BLOWFISH_VALIDATE_RET( output != NULL );
- GET_UINT32_BE( X0, input, 0 );
- GET_UINT32_BE( X1, input, 4 );
+ X0 = MBEDTLS_GET_UINT32_BE( input, 0 );
+ X1 = MBEDTLS_GET_UINT32_BE( input, 4 );
if( mode == MBEDTLS_BLOWFISH_DECRYPT )
{
@@ -285,8 +231,8 @@ int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx,
blowfish_enc( ctx, &X0, &X1 );
}
- PUT_UINT32_BE( X0, output, 0 );
- PUT_UINT32_BE( X1, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( X0, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X1, output, 4 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/camellia.c b/thirdparty/mbedtls/library/camellia.c
index 6cf265e578..29d730ab53 100644
--- a/thirdparty/mbedtls/library/camellia.c
+++ b/thirdparty/mbedtls/library/camellia.c
@@ -2,13 +2,7 @@
* Camellia implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The Camellia block cipher was designed by NTT and Mitsubishi Electric
@@ -50,11 +23,7 @@
* http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CAMELLIA_C)
@@ -80,29 +49,6 @@
#define CAMELLIA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
static const unsigned char SIGMA_CHARS[6][8] =
{
{ 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b },
@@ -332,14 +278,14 @@ static void camellia_feistel( const uint32_t x[2], const uint32_t k[2],
I0 = x[0] ^ k[0];
I1 = x[1] ^ k[1];
- I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX4((I0 ) & 0xFF) );
- I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) |
- ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) |
- ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) |
- ((uint32_t) SBOX1((I1 ) & 0xFF) );
+ I0 = ((uint32_t) SBOX1( MBEDTLS_BYTE_3( I0 )) << 24) |
+ ((uint32_t) SBOX2( MBEDTLS_BYTE_2( I0 )) << 16) |
+ ((uint32_t) SBOX3( MBEDTLS_BYTE_1( I0 )) << 8) |
+ ((uint32_t) SBOX4( MBEDTLS_BYTE_0( I0 )) );
+ I1 = ((uint32_t) SBOX2( MBEDTLS_BYTE_3( I1 )) << 24) |
+ ((uint32_t) SBOX3( MBEDTLS_BYTE_2( I1 )) << 16) |
+ ((uint32_t) SBOX4( MBEDTLS_BYTE_1( I1 )) << 8) |
+ ((uint32_t) SBOX1( MBEDTLS_BYTE_0( I1 )) );
I0 ^= (I1 << 8) | (I1 >> 24);
I1 ^= (I0 << 16) | (I0 >> 16);
@@ -407,8 +353,8 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
* Prepare SIGMA values
*/
for( i = 0; i < 6; i++ ) {
- GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 );
- GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 );
+ SIGMA[i][0] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 0 );
+ SIGMA[i][1] = MBEDTLS_GET_UINT32_BE( SIGMA_CHARS[i], 4 );
}
/*
@@ -419,7 +365,7 @@ int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx,
/* Store KL, KR */
for( i = 0; i < 8; i++ )
- GET_UINT32_BE( KC[i], t, i * 4 );
+ KC[i] = MBEDTLS_GET_UINT32_BE( t, i * 4 );
/* Generate KA */
for( i = 0; i < 4; ++i )
@@ -545,10 +491,10 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
NR = ctx->nr;
RK = ctx->rk;
- GET_UINT32_BE( X[0], input, 0 );
- GET_UINT32_BE( X[1], input, 4 );
- GET_UINT32_BE( X[2], input, 8 );
- GET_UINT32_BE( X[3], input, 12 );
+ X[0] = MBEDTLS_GET_UINT32_BE( input, 0 );
+ X[1] = MBEDTLS_GET_UINT32_BE( input, 4 );
+ X[2] = MBEDTLS_GET_UINT32_BE( input, 8 );
+ X[3] = MBEDTLS_GET_UINT32_BE( input, 12 );
X[0] ^= *RK++;
X[1] ^= *RK++;
@@ -583,10 +529,10 @@ int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx,
X[0] ^= *RK++;
X[1] ^= *RK++;
- PUT_UINT32_BE( X[2], output, 0 );
- PUT_UINT32_BE( X[3], output, 4 );
- PUT_UINT32_BE( X[0], output, 8 );
- PUT_UINT32_BE( X[1], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( X[2], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X[3], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( X[0], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( X[1], output, 12 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c
index b2e5a4763d..a21a37f55f 100644
--- a/thirdparty/mbedtls/library/ccm.c
+++ b/thirdparty/mbedtls/library/ccm.c
@@ -2,13 +2,7 @@
* NIST SP800-38C compliant CCM implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -53,16 +26,13 @@
* RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CCM_C)
#include "mbedtls/ccm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -99,13 +69,14 @@ int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
const unsigned char *key,
unsigned int keybits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
CCM_VALIDATE_RET( ctx != NULL );
CCM_VALIDATE_RET( key != NULL );
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+ cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
+ MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -180,7 +151,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
const unsigned char *input, unsigned char *output,
unsigned char *tag, size_t tag_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i;
unsigned char q;
size_t len_left, olen;
@@ -204,7 +175,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( iv_len < 7 || iv_len > 13 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
- if( add_len > 0xFF00 )
+ if( add_len >= 0xFF00 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
q = 16 - 1 - (unsigned char) iv_len;
@@ -229,7 +200,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
memcpy( b + 1, iv, iv_len );
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
- b[15-i] = (unsigned char)( len_left & 0xFF );
+ b[15-i] = MBEDTLS_BYTE_0( len_left );
if( len_left > 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
@@ -250,8 +221,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
src = add;
memset( b, 0, 16 );
- b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
- b[1] = (unsigned char)( ( add_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( add_len, b, 0 );
use_len = len_left < 16 - 2 ? len_left : 16 - 2;
memcpy( b + 2, src, use_len );
@@ -390,7 +360,7 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
const unsigned char *input, unsigned char *output,
const unsigned char *tag, size_t tag_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
unsigned char i;
int diff;
@@ -454,34 +424,34 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
/*
* The data is the same for all tests, only the used length changes
*/
-static const unsigned char key[] = {
+static const unsigned char key_test_data[] = {
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
};
-static const unsigned char iv[] = {
+static const unsigned char iv_test_data[] = {
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b
};
-static const unsigned char ad[] = {
+static const unsigned char ad_test_data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13
};
-static const unsigned char msg[CCM_SELFTEST_PT_MAX_LEN] = {
+static const unsigned char msg_test_data[CCM_SELFTEST_PT_MAX_LEN] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};
-static const size_t iv_len [NB_TESTS] = { 7, 8, 12 };
-static const size_t add_len[NB_TESTS] = { 8, 16, 20 };
-static const size_t msg_len[NB_TESTS] = { 4, 16, 24 };
-static const size_t tag_len[NB_TESTS] = { 4, 6, 8 };
+static const size_t iv_len_test_data [NB_TESTS] = { 7, 8, 12 };
+static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 };
+static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 };
+static const size_t tag_len_test_data[NB_TESTS] = { 4, 6, 8 };
-static const unsigned char res[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
+static const unsigned char res_test_data[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
{ 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
{ 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
@@ -503,11 +473,12 @@ int mbedtls_ccm_self_test( int verbose )
unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
size_t i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ccm_init( &ctx );
- if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 )
+ if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key_test_data,
+ 8 * sizeof key_test_data ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( " CCM: setup failed" );
@@ -522,15 +493,18 @@ int mbedtls_ccm_self_test( int verbose )
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
- memcpy( plaintext, msg, msg_len[i] );
+ memcpy( plaintext, msg_test_data, msg_len_test_data[i] );
- ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
+ ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len_test_data[i],
+ iv_test_data, iv_len_test_data[i],
+ ad_test_data, add_len_test_data[i],
plaintext, ciphertext,
- ciphertext + msg_len[i], tag_len[i] );
+ ciphertext + msg_len_test_data[i],
+ tag_len_test_data[i] );
if( ret != 0 ||
- memcmp( ciphertext, res[i], msg_len[i] + tag_len[i] ) != 0 )
+ memcmp( ciphertext, res_test_data[i],
+ msg_len_test_data[i] + tag_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
@@ -539,13 +513,15 @@ int mbedtls_ccm_self_test( int verbose )
}
memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
- ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i],
- iv, iv_len[i], ad, add_len[i],
+ ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len_test_data[i],
+ iv_test_data, iv_len_test_data[i],
+ ad_test_data, add_len_test_data[i],
ciphertext, plaintext,
- ciphertext + msg_len[i], tag_len[i] );
+ ciphertext + msg_len_test_data[i],
+ tag_len_test_data[i] );
if( ret != 0 ||
- memcmp( plaintext, msg, msg_len[i] ) != 0 )
+ memcmp( plaintext, msg_test_data, msg_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
diff --git a/thirdparty/mbedtls/library/certs.c b/thirdparty/mbedtls/library/certs.c
index cb43f53368..a5695e3c8e 100644
--- a/thirdparty/mbedtls/library/certs.c
+++ b/thirdparty/mbedtls/library/certs.c
@@ -2,13 +2,7 @@
* X.509 test certificates
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include "mbedtls/certs.h"
@@ -279,7 +248,7 @@
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
- "MTkwMjEwMTQ0NDAwWhcNMjkwMjEwMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \
+ "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \
"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \
"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \
"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \
@@ -289,88 +258,88 @@
"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \
"UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \
"MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \
- "A4IBAQB0ZiNRFdia6kskaPnhrqejIRq8YMEGAf2oIPnyZ78xoyERgc35lHGyMtsL\r\n" \
- "hWicNjP4d/hS9As4j5KA2gdNGi5ETA1X7SowWOGsryivSpMSHVy1+HdfWlsYQOzm\r\n" \
- "8o+faQNUm8XzPVmttfAVspxeHSxJZ36Oo+QWZ5wZlCIEyjEdLUId+Tm4Bz3B5jRD\r\n" \
- "zZa/SaqDokq66N2zpbgKKAl3GU2O++fBqP2dSkdQykmTxhLLWRN8FJqhYATyQntZ\r\n" \
- "0QSi3W9HfSZPnFTcPIXeoiPd2pLlxt1hZu8dws2LTXE63uP6MM4LHvWxiuJaWkP/\r\n" \
- "mtxyUALj2pQxRitopORFQdn7AOY5\r\n" \
+ "A4IBAQABE3OEPfEd/bcJW5ZdU3/VgPNS4tMzh8gnJP/V2FcvFtGylMpQq6YnEBYI\r\n" \
+ "yBHAL4DRvlMY5rnXGBp3ODR8MpqHC6AquRTCLzjS57iYff//4QFQqW9n92zctspv\r\n" \
+ "czkaPKgjqo1No3Uq0Xaz10rcxyTUPrf5wNVRZ2V0KvllvAAVSzbI4mpdUXztjhST\r\n" \
+ "S5A2BeWQAAOr0zq1F7TSRVJpJs7jmB2ai/igkh1IAjcuwV6VwlP+sbw0gjQ0NpGM\r\n" \
+ "iHpnlzRAi/tIbtOvMIGOBU2TIfax/5jq1agUx5aPmT5TWAiJPOOP6l5xXnDwxeYS\r\n" \
+ "NWqiX9GyusBZjezaCaHabjDLU0qQ\r\n" \
"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is taken from tests/data_files/test-ca-sha1.crt.der. */
/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */
#define TEST_CA_CRT_RSA_SHA1_DER { \
- 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \
- 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \
- 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \
- 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \
- 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \
- 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \
- 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \
- 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \
- 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \
- 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \
- 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \
- 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \
- 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \
- 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \
- 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \
- 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \
- 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \
- 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \
- 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \
- 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \
- 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \
- 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \
- 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \
- 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \
- 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \
- 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \
- 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \
- 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \
- 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \
- 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \
- 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \
- 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \
- 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \
- 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0x66, 0x23, 0x51, 0x15, 0xd8, 0x9a, \
- 0xea, 0x4b, 0x24, 0x68, 0xf9, 0xe1, 0xae, 0xa7, 0xa3, 0x21, 0x1a, 0xbc, \
- 0x60, 0xc1, 0x06, 0x01, 0xfd, 0xa8, 0x20, 0xf9, 0xf2, 0x67, 0xbf, 0x31, \
- 0xa3, 0x21, 0x11, 0x81, 0xcd, 0xf9, 0x94, 0x71, 0xb2, 0x32, 0xdb, 0x0b, \
- 0x85, 0x68, 0x9c, 0x36, 0x33, 0xf8, 0x77, 0xf8, 0x52, 0xf4, 0x0b, 0x38, \
- 0x8f, 0x92, 0x80, 0xda, 0x07, 0x4d, 0x1a, 0x2e, 0x44, 0x4c, 0x0d, 0x57, \
- 0xed, 0x2a, 0x30, 0x58, 0xe1, 0xac, 0xaf, 0x28, 0xaf, 0x4a, 0x93, 0x12, \
- 0x1d, 0x5c, 0xb5, 0xf8, 0x77, 0x5f, 0x5a, 0x5b, 0x18, 0x40, 0xec, 0xe6, \
- 0xf2, 0x8f, 0x9f, 0x69, 0x03, 0x54, 0x9b, 0xc5, 0xf3, 0x3d, 0x59, 0xad, \
- 0xb5, 0xf0, 0x15, 0xb2, 0x9c, 0x5e, 0x1d, 0x2c, 0x49, 0x67, 0x7e, 0x8e, \
- 0xa3, 0xe4, 0x16, 0x67, 0x9c, 0x19, 0x94, 0x22, 0x04, 0xca, 0x31, 0x1d, \
- 0x2d, 0x42, 0x1d, 0xf9, 0x39, 0xb8, 0x07, 0x3d, 0xc1, 0xe6, 0x34, 0x43, \
- 0xcd, 0x96, 0xbf, 0x49, 0xaa, 0x83, 0xa2, 0x4a, 0xba, 0xe8, 0xdd, 0xb3, \
- 0xa5, 0xb8, 0x0a, 0x28, 0x09, 0x77, 0x19, 0x4d, 0x8e, 0xfb, 0xe7, 0xc1, \
- 0xa8, 0xfd, 0x9d, 0x4a, 0x47, 0x50, 0xca, 0x49, 0x93, 0xc6, 0x12, 0xcb, \
- 0x59, 0x13, 0x7c, 0x14, 0x9a, 0xa1, 0x60, 0x04, 0xf2, 0x42, 0x7b, 0x59, \
- 0xd1, 0x04, 0xa2, 0xdd, 0x6f, 0x47, 0x7d, 0x26, 0x4f, 0x9c, 0x54, 0xdc, \
- 0x3c, 0x85, 0xde, 0xa2, 0x23, 0xdd, 0xda, 0x92, 0xe5, 0xc6, 0xdd, 0x61, \
- 0x66, 0xef, 0x1d, 0xc2, 0xcd, 0x8b, 0x4d, 0x71, 0x3a, 0xde, 0xe3, 0xfa, \
- 0x30, 0xce, 0x0b, 0x1e, 0xf5, 0xb1, 0x8a, 0xe2, 0x5a, 0x5a, 0x43, 0xff, \
- 0x9a, 0xdc, 0x72, 0x50, 0x02, 0xe3, 0xda, 0x94, 0x31, 0x46, 0x2b, 0x68, \
- 0xa4, 0xe4, 0x45, 0x41, 0xd9, 0xfb, 0x00, 0xe6, 0x39 \
+ 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \
+ 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \
+ 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \
+ 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \
+ 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \
+ 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \
+ 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \
+ 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \
+ 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \
+ 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \
+ 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \
+ 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \
+ 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \
+ 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \
+ 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \
+ 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \
+ 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \
+ 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \
+ 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \
+ 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \
+ 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \
+ 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \
+ 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \
+ 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \
+ 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \
+ 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \
+ 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \
+ 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \
+ 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \
+ 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \
+ 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \
+ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \
+ 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x13, 0x73, 0x84, 0x3d, 0xf1, 0x1d, \
+ 0xfd, 0xb7, 0x09, 0x5b, 0x96, 0x5d, 0x53, 0x7f, 0xd5, 0x80, 0xf3, 0x52, \
+ 0xe2, 0xd3, 0x33, 0x87, 0xc8, 0x27, 0x24, 0xff, 0xd5, 0xd8, 0x57, 0x2f, \
+ 0x16, 0xd1, 0xb2, 0x94, 0xca, 0x50, 0xab, 0xa6, 0x27, 0x10, 0x16, 0x08, \
+ 0xc8, 0x11, 0xc0, 0x2f, 0x80, 0xd1, 0xbe, 0x53, 0x18, 0xe6, 0xb9, 0xd7, \
+ 0x18, 0x1a, 0x77, 0x38, 0x34, 0x7c, 0x32, 0x9a, 0x87, 0x0b, 0xa0, 0x2a, \
+ 0xb9, 0x14, 0xc2, 0x2f, 0x38, 0xd2, 0xe7, 0xb8, 0x98, 0x7d, 0xff, 0xff, \
+ 0xe1, 0x01, 0x50, 0xa9, 0x6f, 0x67, 0xf7, 0x6c, 0xdc, 0xb6, 0xca, 0x6f, \
+ 0x73, 0x39, 0x1a, 0x3c, 0xa8, 0x23, 0xaa, 0x8d, 0x4d, 0xa3, 0x75, 0x2a, \
+ 0xd1, 0x76, 0xb3, 0xd7, 0x4a, 0xdc, 0xc7, 0x24, 0xd4, 0x3e, 0xb7, 0xf9, \
+ 0xc0, 0xd5, 0x51, 0x67, 0x65, 0x74, 0x2a, 0xf9, 0x65, 0xbc, 0x00, 0x15, \
+ 0x4b, 0x36, 0xc8, 0xe2, 0x6a, 0x5d, 0x51, 0x7c, 0xed, 0x8e, 0x14, 0x93, \
+ 0x4b, 0x90, 0x36, 0x05, 0xe5, 0x90, 0x00, 0x03, 0xab, 0xd3, 0x3a, 0xb5, \
+ 0x17, 0xb4, 0xd2, 0x45, 0x52, 0x69, 0x26, 0xce, 0xe3, 0x98, 0x1d, 0x9a, \
+ 0x8b, 0xf8, 0xa0, 0x92, 0x1d, 0x48, 0x02, 0x37, 0x2e, 0xc1, 0x5e, 0x95, \
+ 0xc2, 0x53, 0xfe, 0xb1, 0xbc, 0x34, 0x82, 0x34, 0x34, 0x36, 0x91, 0x8c, \
+ 0x88, 0x7a, 0x67, 0x97, 0x34, 0x40, 0x8b, 0xfb, 0x48, 0x6e, 0xd3, 0xaf, \
+ 0x30, 0x81, 0x8e, 0x05, 0x4d, 0x93, 0x21, 0xf6, 0xb1, 0xff, 0x98, 0xea, \
+ 0xd5, 0xa8, 0x14, 0xc7, 0x96, 0x8f, 0x99, 0x3e, 0x53, 0x58, 0x08, 0x89, \
+ 0x3c, 0xe3, 0x8f, 0xea, 0x5e, 0x71, 0x5e, 0x70, 0xf0, 0xc5, 0xe6, 0x12, \
+ 0x35, 0x6a, 0xa2, 0x5f, 0xd1, 0xb2, 0xba, 0xc0, 0x59, 0x8d, 0xec, 0xda, \
+ 0x09, 0xa1, 0xda, 0x6e, 0x30, 0xcb, 0x53, 0x4a, 0x90 \
}
/* END FILE */
@@ -730,101 +699,101 @@
/* This is taken from tests/data_files/server2.crt. */
/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */
-#define TEST_SRV_CRT_RSA_SHA1_PEM \
- "-----BEGIN CERTIFICATE-----\r\n" \
- "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
- "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
- "MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \
- "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \
- "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \
- "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \
- "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \
- "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \
- "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \
- "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \
- "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \
- "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \
- "cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \
- "O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \
- "KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \
- "iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \
- "HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \
- "Awgk0+4m0T25cNs=\r\n" \
- "-----END CERTIFICATE-----\r\n"
+#define TEST_SRV_CRT_RSA_SHA1_PEM \
+"-----BEGIN CERTIFICATE-----\r\n" \
+"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \
+"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \
+"MTkwMjEwMTQ0NDA2WhcNMjkwMjEwMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \
+"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \
+"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \
+"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \
+"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \
+"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \
+"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \
+"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \
+"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \
+"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJklg3Q4\r\n" \
+"cB7v7BzsxM/vLyKccO6op0/gZzM4ghuLq2Y32kl0sM6kSNUUmduuq3u/+GmUZN2A\r\n" \
+"O/7c+Hw7hDFEIvZk98aBGjCLqn3DmgHIv8ToQ67nellQxx2Uj309PdgjNi/r9HOc\r\n" \
+"KNAYPbBcg6MJGWWj2TI6vNaceios/DhOYx5V0j5nfqSJ/pnU0g9Ign2LAhgYpGJE\r\n" \
+"iEM9wW7hEMkwmk0h/sqZsrJsGH5YsF/VThSq/JVO1e2mZH2vruyZKJVBq+8tDNYp\r\n" \
+"HkK6tSyVYQhzIt3StMJWKMl/o5k2AYz6tSC164+1oG+ML3LWg8XrGKa91H4UOKap\r\n" \
+"Awgk0+4m0T25cNs=\r\n" \
+"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is taken from tests/data_files/server2.crt.der. */
/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */
#define TEST_SRV_CRT_RSA_SHA1_DER { \
- 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \
- 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \
- 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \
- 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \
- 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \
- 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \
- 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \
- 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \
- 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \
- 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \
- 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \
- 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \
- 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \
- 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \
- 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \
- 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \
- 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \
- 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \
- 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \
- 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \
- 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \
- 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \
- 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \
- 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \
- 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \
- 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \
- 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \
- 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \
- 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \
- 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \
- 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \
- 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \
- 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x99, 0x25, 0x83, 0x74, 0x38, \
- 0x70, 0x1e, 0xef, 0xec, 0x1c, 0xec, 0xc4, 0xcf, 0xef, 0x2f, 0x22, 0x9c, \
- 0x70, 0xee, 0xa8, 0xa7, 0x4f, 0xe0, 0x67, 0x33, 0x38, 0x82, 0x1b, 0x8b, \
- 0xab, 0x66, 0x37, 0xda, 0x49, 0x74, 0xb0, 0xce, 0xa4, 0x48, 0xd5, 0x14, \
- 0x99, 0xdb, 0xae, 0xab, 0x7b, 0xbf, 0xf8, 0x69, 0x94, 0x64, 0xdd, 0x80, \
- 0x3b, 0xfe, 0xdc, 0xf8, 0x7c, 0x3b, 0x84, 0x31, 0x44, 0x22, 0xf6, 0x64, \
- 0xf7, 0xc6, 0x81, 0x1a, 0x30, 0x8b, 0xaa, 0x7d, 0xc3, 0x9a, 0x01, 0xc8, \
- 0xbf, 0xc4, 0xe8, 0x43, 0xae, 0xe7, 0x7a, 0x59, 0x50, 0xc7, 0x1d, 0x94, \
- 0x8f, 0x7d, 0x3d, 0x3d, 0xd8, 0x23, 0x36, 0x2f, 0xeb, 0xf4, 0x73, 0x9c, \
- 0x28, 0xd0, 0x18, 0x3d, 0xb0, 0x5c, 0x83, 0xa3, 0x09, 0x19, 0x65, 0xa3, \
- 0xd9, 0x32, 0x3a, 0xbc, 0xd6, 0x9c, 0x7a, 0x2a, 0x2c, 0xfc, 0x38, 0x4e, \
- 0x63, 0x1e, 0x55, 0xd2, 0x3e, 0x67, 0x7e, 0xa4, 0x89, 0xfe, 0x99, 0xd4, \
- 0xd2, 0x0f, 0x48, 0x82, 0x7d, 0x8b, 0x02, 0x18, 0x18, 0xa4, 0x62, 0x44, \
- 0x88, 0x43, 0x3d, 0xc1, 0x6e, 0xe1, 0x10, 0xc9, 0x30, 0x9a, 0x4d, 0x21, \
- 0xfe, 0xca, 0x99, 0xb2, 0xb2, 0x6c, 0x18, 0x7e, 0x58, 0xb0, 0x5f, 0xd5, \
- 0x4e, 0x14, 0xaa, 0xfc, 0x95, 0x4e, 0xd5, 0xed, 0xa6, 0x64, 0x7d, 0xaf, \
- 0xae, 0xec, 0x99, 0x28, 0x95, 0x41, 0xab, 0xef, 0x2d, 0x0c, 0xd6, 0x29, \
- 0x1e, 0x42, 0xba, 0xb5, 0x2c, 0x95, 0x61, 0x08, 0x73, 0x22, 0xdd, 0xd2, \
- 0xb4, 0xc2, 0x56, 0x28, 0xc9, 0x7f, 0xa3, 0x99, 0x36, 0x01, 0x8c, 0xfa, \
- 0xb5, 0x20, 0xb5, 0xeb, 0x8f, 0xb5, 0xa0, 0x6f, 0x8c, 0x2f, 0x72, 0xd6, \
- 0x83, 0xc5, 0xeb, 0x18, 0xa6, 0xbd, 0xd4, 0x7e, 0x14, 0x38, 0xa6, 0xa9, \
- 0x03, 0x08, 0x24, 0xd3, 0xee, 0x26, 0xd1, 0x3d, 0xb9, 0x70, 0xdb \
+ 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \
+ 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \
+ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \
+ 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \
+ 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \
+ 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \
+ 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \
+ 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \
+ 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \
+ 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \
+ 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \
+ 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \
+ 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \
+ 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \
+ 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \
+ 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \
+ 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \
+ 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \
+ 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \
+ 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \
+ 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \
+ 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \
+ 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \
+ 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \
+ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \
+ 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \
+ 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \
+ 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \
+ 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \
+ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \
+ 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x73, 0x0b, 0x4a, 0xc5, \
+ 0xcb, 0xa0, 0xde, 0xf1, 0x63, 0x1c, 0x76, 0x04, 0x2b, 0x13, 0x0d, 0xc0, \
+ 0x84, 0x11, 0xc5, 0x8f, 0x3a, 0xa7, 0xc5, 0x9c, 0x35, 0x7a, 0x77, 0xb8, \
+ 0x20, 0x14, 0x82, 0xee, 0x54, 0xf0, 0xf2, 0xb0, 0x52, 0xcb, 0x78, 0xce, \
+ 0x59, 0x07, 0x4f, 0x51, 0x69, 0xfe, 0xd3, 0x2f, 0xe9, 0x09, 0xe7, 0x85, \
+ 0x92, 0xd8, 0xba, 0xb1, 0xeb, 0xc5, 0x76, 0x5d, 0x61, 0x2d, 0xe9, 0x86, \
+ 0xb5, 0xde, 0x2a, 0xf9, 0x3f, 0x53, 0x28, 0x42, 0x86, 0x83, 0x73, 0x43, \
+ 0xe0, 0x04, 0x5f, 0x07, 0x90, 0x14, 0x65, 0x9f, 0x6e, 0x10, 0x7a, 0xbc, \
+ 0x58, 0x19, 0x22, 0xc2, 0xeb, 0x39, 0x72, 0x51, 0x92, 0xd7, 0xb4, 0x1d, \
+ 0x75, 0x2f, 0xd3, 0x3a, 0x2b, 0x01, 0xe7, 0xdb, 0x50, 0xae, 0xe2, 0xf1, \
+ 0xd4, 0x4d, 0x5b, 0x3c, 0xbb, 0x41, 0x2b, 0x2a, 0xa4, 0xe2, 0x4a, 0x02, \
+ 0xe5, 0x60, 0x14, 0x2c, 0x9c, 0x1f, 0xa6, 0xcc, 0x06, 0x4b, 0x25, 0x89, \
+ 0x4e, 0x96, 0x30, 0x22, 0x9c, 0x5c, 0x58, 0x4d, 0xc3, 0xda, 0xd0, 0x6e, \
+ 0x50, 0x1e, 0x8c, 0x65, 0xf5, 0xd9, 0x17, 0x35, 0xa6, 0x58, 0x43, 0xb2, \
+ 0x29, 0xb7, 0xa8, 0x5e, 0x35, 0xde, 0xf0, 0x60, 0x42, 0x1a, 0x01, 0xcb, \
+ 0xcb, 0x0b, 0xd8, 0x0e, 0xc1, 0x90, 0xdf, 0xa1, 0xd2, 0x1a, 0xd1, 0x2c, \
+ 0x02, 0xf4, 0x76, 0x41, 0xa4, 0xcb, 0x4b, 0x15, 0x98, 0x71, 0xf9, 0x35, \
+ 0x7d, 0xb0, 0xe7, 0xe2, 0x34, 0x96, 0x91, 0xbe, 0x32, 0x67, 0x2d, 0x6b, \
+ 0xd3, 0x55, 0x04, 0x8a, 0x01, 0x50, 0xb4, 0xe3, 0x62, 0x78, 0x6c, 0x11, \
+ 0x15, 0xa5, 0x2a, 0x11, 0xc1, 0x49, 0x1c, 0x9b, 0xc4, 0x10, 0x65, 0x60, \
+ 0x87, 0xd9, 0x1e, 0x69, 0x59, 0x4e, 0x8f, 0x6b, 0xeb, 0xc1, 0xfe, 0x6b, \
+ 0xe2, 0x63, 0x78, 0x95, 0x6e, 0xe0, 0x2d, 0xd7, 0xa7, 0x37, 0xa8 \
}
/* END FILE */
@@ -993,54 +962,54 @@
"IwQYMBaAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8MAwGCCqGSM49BAMCBQADaAAwZQIx\r\n" \
"AMqme4DKMldUlplDET9Q6Eptre7uUWKhsLOF+zPkKDlfzpIkJYEFgcloDHGYw80u\r\n" \
"IgIwNftyPXsabTqMM7iEHgVpX/GRozKklY9yQI/5eoA6gGW7Y+imuGR/oao5ySOb\r\n" \
- "a9Vk\r\n" \
+ "a9Vk\r\n" \
"-----END CERTIFICATE-----\r\n"
/* END FILE */
/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */
/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */
#define TEST_CLI_CRT_EC_DER { \
- 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \
- 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
- 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
- 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \
- 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \
- 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \
- 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \
- 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \
- 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
- 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
- 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \
- 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
- 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \
- 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
- 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \
- 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \
- 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \
- 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \
- 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \
- 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \
- 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \
- 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \
- 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \
- 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \
- 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \
- 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \
- 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \
- 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
- 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \
- 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \
- 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \
- 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \
- 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \
- 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \
- 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \
- 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \
- 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \
- 0x6b, 0xd5, 0x64 \
+ 0x30, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, 0x63, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \
+ 0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
+ 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
+ 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \
+ 0x03, 0x0c, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, \
+ 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, \
+ 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, \
+ 0x34, 0x34, 0x34, 0x30, 0x30, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, \
+ 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \
+ 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, \
+ 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, \
+ 0x03, 0x0c, 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, \
+ 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, \
+ 0x32, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
+ 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, \
+ 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, \
+ 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, \
+ 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, \
+ 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, \
+ 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, \
+ 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x4d, 0x30, 0x4b, \
+ 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \
+ 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \
+ 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \
+ 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, \
+ 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \
+ 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \
+ 0xfb, 0x36, 0x7c, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \
+ 0x04, 0x03, 0x02, 0x05, 0x00, 0x03, 0x68, 0x00, 0x30, 0x65, 0x02, 0x31, \
+ 0x00, 0xca, 0xa6, 0x7b, 0x80, 0xca, 0x32, 0x57, 0x54, 0x96, 0x99, 0x43, \
+ 0x11, 0x3f, 0x50, 0xe8, 0x4a, 0x6d, 0xad, 0xee, 0xee, 0x51, 0x62, 0xa1, \
+ 0xb0, 0xb3, 0x85, 0xfb, 0x33, 0xe4, 0x28, 0x39, 0x5f, 0xce, 0x92, 0x24, \
+ 0x25, 0x81, 0x05, 0x81, 0xc9, 0x68, 0x0c, 0x71, 0x98, 0xc3, 0xcd, 0x2e, \
+ 0x22, 0x02, 0x30, 0x35, 0xfb, 0x72, 0x3d, 0x7b, 0x1a, 0x6d, 0x3a, 0x8c, \
+ 0x33, 0xb8, 0x84, 0x1e, 0x05, 0x69, 0x5f, 0xf1, 0x91, 0xa3, 0x32, 0xa4, \
+ 0x95, 0x8f, 0x72, 0x40, 0x8f, 0xf9, 0x7a, 0x80, 0x3a, 0x80, 0x65, 0xbb, \
+ 0x63, 0xe8, 0xa6, 0xb8, 0x64, 0x7f, 0xa1, 0xaa, 0x39, 0xc9, 0x23, 0x9b, \
+ 0x6b, 0xd5, 0x64 \
}
/* END FILE */
@@ -1100,76 +1069,76 @@
using `xxd -i.` */
/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */
#define TEST_CLI_CRT_RSA_DER { \
- 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \
- 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
- 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
- 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
- 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
- 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
- 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
- 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
- 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
- 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
- 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
- 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
- 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
- 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
- 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \
- 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \
- 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \
- 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \
- 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \
- 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \
- 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \
- 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \
- 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \
- 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \
- 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \
- 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \
- 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \
- 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \
- 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \
- 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \
- 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \
- 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \
- 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \
- 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \
- 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \
- 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \
- 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \
- 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \
- 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \
- 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \
- 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \
- 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \
- 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \
- 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \
- 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \
- 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \
- 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \
- 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \
- 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \
- 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \
- 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \
- 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \
- 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \
- 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \
- 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \
- 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \
- 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \
- 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \
- 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \
- 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \
- 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \
- 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \
- 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \
- 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \
- 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \
- 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \
- 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \
- 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \
- 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \
- 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \
+ 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \
+ 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \
+ 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \
+ 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \
+ 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \
+ 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \
+ 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \
+ 0x31, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \
+ 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x34, \
+ 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \
+ 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \
+ 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \
+ 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \
+ 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \
+ 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \
+ 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \
+ 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \
+ 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \
+ 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \
+ 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \
+ 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \
+ 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \
+ 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \
+ 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \
+ 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \
+ 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \
+ 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \
+ 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \
+ 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \
+ 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \
+ 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \
+ 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \
+ 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \
+ 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \
+ 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \
+ 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \
+ 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \
+ 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \
+ 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \
+ 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \
+ 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \
+ 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \
+ 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \
+ 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \
+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \
+ 0x01, 0x01, 0x00, 0x5e, 0x27, 0x6f, 0xd5, 0xde, 0x29, 0x2e, 0x50, 0x62, \
+ 0x29, 0x61, 0x03, 0xf7, 0x9a, 0xcc, 0xc9, 0xc0, 0x5d, 0x80, 0x37, 0x20, \
+ 0xc8, 0xda, 0x89, 0xc5, 0xa9, 0x05, 0x91, 0x17, 0xd1, 0xc8, 0x0d, 0xb2, \
+ 0xd6, 0x69, 0x72, 0x4e, 0x7e, 0xee, 0x05, 0x74, 0x64, 0x34, 0xb6, 0x39, \
+ 0x64, 0x5c, 0xca, 0xf3, 0x61, 0x82, 0x8e, 0x4d, 0x90, 0xd8, 0xe0, 0xf8, \
+ 0x45, 0x94, 0x82, 0x3c, 0x02, 0x49, 0xa8, 0xba, 0x47, 0x1d, 0x4d, 0xf8, \
+ 0xb7, 0xbd, 0x5c, 0x89, 0xf7, 0xef, 0xcb, 0x62, 0x8a, 0xf3, 0x56, 0x2f, \
+ 0xaf, 0x17, 0x33, 0x46, 0x13, 0x00, 0x13, 0xae, 0x22, 0xfa, 0xa9, 0xda, \
+ 0xc8, 0xfd, 0xd3, 0x77, 0x65, 0xee, 0x58, 0x94, 0x74, 0xe4, 0xf5, 0x4f, \
+ 0xa1, 0x27, 0xa6, 0xb0, 0xd1, 0x0b, 0xb3, 0xd8, 0x16, 0xb6, 0xd7, 0x67, \
+ 0x63, 0x2d, 0xdc, 0x7b, 0xe1, 0x18, 0xd9, 0x8d, 0x27, 0xed, 0x1b, 0x22, \
+ 0xef, 0xdf, 0x36, 0x11, 0xe2, 0xc8, 0x00, 0x0e, 0xc7, 0xe9, 0xc6, 0xb8, \
+ 0xd8, 0x4b, 0x3f, 0x35, 0x41, 0xff, 0xfc, 0x96, 0x49, 0x4f, 0x7d, 0x8e, \
+ 0x3f, 0x47, 0x68, 0x33, 0x17, 0x83, 0x44, 0x0f, 0xaf, 0xa6, 0x59, 0x0a, \
+ 0xa9, 0x32, 0xcb, 0x59, 0xfe, 0xdd, 0x5f, 0x6e, 0x8b, 0x22, 0xb8, 0x81, \
+ 0x90, 0x16, 0x91, 0x0a, 0x04, 0x79, 0x62, 0xff, 0x4b, 0x04, 0xf1, 0x5c, \
+ 0x34, 0xeb, 0x69, 0xce, 0xef, 0xcb, 0x6e, 0xb6, 0x3b, 0x40, 0x55, 0xca, \
+ 0x24, 0xc2, 0x3e, 0x25, 0x70, 0xee, 0x74, 0x2b, 0x0e, 0x9f, 0xc2, 0x82, \
+ 0x9a, 0x20, 0x38, 0x77, 0xa1, 0x26, 0x8a, 0xca, 0x9f, 0x87, 0x75, 0x77, \
+ 0xe3, 0xce, 0x65, 0xec, 0x71, 0x10, 0x35, 0xcb, 0xcb, 0x4f, 0x19, 0x43, \
+ 0xeb, 0x30, 0xd0, 0xca, 0x2d, 0x3f, 0xca, 0x46, 0x14, 0x61, 0x99, 0x30, \
+ 0x41, 0x32, 0xb5, 0x37, 0x63, 0x6f, 0x97 \
}
/* END FILE */
@@ -1643,7 +1612,6 @@ const size_t mbedtls_test_srv_crt_rsa_len =
#define TEST_CLI_KEY TEST_CLI_KEY_EC
#define TEST_CLI_PWD TEST_CLI_PWD_EC
#define TEST_CLI_CRT TEST_CLI_CRT_EC
-
#endif /* MBEDTLS_RSA_C */
/* API stability forces us to declare
diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c
index 80fe50cc67..658f046901 100644
--- a/thirdparty/mbedtls/library/chacha20.c
+++ b/thirdparty/mbedtls/library/chacha20.c
@@ -6,13 +6,7 @@
* \author Daniel King <damaki.gh@gmail.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,39 +19,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CHACHA20_C)
#include "mbedtls/chacha20.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <stddef.h>
#include <string.h>
@@ -84,13 +54,6 @@
#define CHACHA20_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#define BYTES_TO_U32_LE( data, offset ) \
- ( (uint32_t) (data)[offset] \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
- )
-
#define ROTL32( value, amount ) \
( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) )
@@ -201,10 +164,7 @@ static void chacha20_block( const uint32_t initial_state[16],
{
size_t offset = i * 4U;
- keystream[offset ] = (unsigned char)( working_state[i] );
- keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 );
- keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 );
- keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 );
+ MBEDTLS_PUT_UINT32_LE(working_state[i], keystream, offset);
}
mbedtls_platform_zeroize( working_state, sizeof( working_state ) );
@@ -242,14 +202,14 @@ int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
ctx->state[3] = 0x6b206574;
/* Set key */
- ctx->state[4] = BYTES_TO_U32_LE( key, 0 );
- ctx->state[5] = BYTES_TO_U32_LE( key, 4 );
- ctx->state[6] = BYTES_TO_U32_LE( key, 8 );
- ctx->state[7] = BYTES_TO_U32_LE( key, 12 );
- ctx->state[8] = BYTES_TO_U32_LE( key, 16 );
- ctx->state[9] = BYTES_TO_U32_LE( key, 20 );
- ctx->state[10] = BYTES_TO_U32_LE( key, 24 );
- ctx->state[11] = BYTES_TO_U32_LE( key, 28 );
+ ctx->state[4] = MBEDTLS_GET_UINT32_LE( key, 0 );
+ ctx->state[5] = MBEDTLS_GET_UINT32_LE( key, 4 );
+ ctx->state[6] = MBEDTLS_GET_UINT32_LE( key, 8 );
+ ctx->state[7] = MBEDTLS_GET_UINT32_LE( key, 12 );
+ ctx->state[8] = MBEDTLS_GET_UINT32_LE( key, 16 );
+ ctx->state[9] = MBEDTLS_GET_UINT32_LE( key, 20 );
+ ctx->state[10] = MBEDTLS_GET_UINT32_LE( key, 24 );
+ ctx->state[11] = MBEDTLS_GET_UINT32_LE( key, 28 );
return( 0 );
}
@@ -265,9 +225,9 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
ctx->state[12] = counter;
/* Nonce */
- ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 );
- ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 );
- ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 );
+ ctx->state[13] = MBEDTLS_GET_UINT32_LE( nonce, 0 );
+ ctx->state[14] = MBEDTLS_GET_UINT32_LE( nonce, 4 );
+ ctx->state[15] = MBEDTLS_GET_UINT32_LE( nonce, 8 );
mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) );
@@ -350,7 +310,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32],
unsigned char* output )
{
mbedtls_chacha20_context ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHA20_VALIDATE_RET( key != NULL );
CHACHA20_VALIDATE_RET( nonce != NULL );
@@ -544,6 +504,9 @@ static const size_t test_lengths[2] =
375U
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -561,7 +524,7 @@ int mbedtls_chacha20_self_test( int verbose )
{
unsigned char output[381];
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
for( i = 0U; i < 2U; i++ )
{
diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c
index c8b5bba4b2..dc75b2030a 100644
--- a/thirdparty/mbedtls/library/chachapoly.c
+++ b/thirdparty/mbedtls/library/chachapoly.c
@@ -4,13 +4,7 @@
* \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539.
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,38 +17,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -147,7 +117,7 @@ void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
const unsigned char key[32] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( key != NULL );
@@ -160,7 +130,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
const unsigned char nonce[12],
mbedtls_chachapoly_mode_t mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char poly1305_key[64];
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( nonce != NULL );
@@ -216,7 +186,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( len == 0 || input != NULL );
CHACHAPOLY_VALIDATE_RET( len == 0 || output != NULL );
@@ -265,7 +235,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
unsigned char mac[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char len_block[16];
CHACHAPOLY_VALIDATE_RET( ctx != NULL );
CHACHAPOLY_VALIDATE_RET( mac != NULL );
@@ -293,22 +263,8 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
/* The lengths of the AAD and ciphertext are processed by
* Poly1305 as the final 128-bit block, encoded as little-endian integers.
*/
- len_block[ 0] = (unsigned char)( ctx->aad_len );
- len_block[ 1] = (unsigned char)( ctx->aad_len >> 8 );
- len_block[ 2] = (unsigned char)( ctx->aad_len >> 16 );
- len_block[ 3] = (unsigned char)( ctx->aad_len >> 24 );
- len_block[ 4] = (unsigned char)( ctx->aad_len >> 32 );
- len_block[ 5] = (unsigned char)( ctx->aad_len >> 40 );
- len_block[ 6] = (unsigned char)( ctx->aad_len >> 48 );
- len_block[ 7] = (unsigned char)( ctx->aad_len >> 56 );
- len_block[ 8] = (unsigned char)( ctx->ciphertext_len );
- len_block[ 9] = (unsigned char)( ctx->ciphertext_len >> 8 );
- len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 );
- len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 );
- len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 );
- len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 );
- len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 );
- len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 );
+ MBEDTLS_PUT_UINT64_LE(ctx->aad_len, len_block, 0);
+ MBEDTLS_PUT_UINT64_LE(ctx->ciphertext_len, len_block, 8);
ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U );
if( ret != 0 )
@@ -329,7 +285,7 @@ static int chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx,
unsigned char *output,
unsigned char tag[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_chachapoly_starts( ctx, nonce, mode );
if( ret != 0 )
@@ -379,7 +335,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
@@ -500,6 +456,9 @@ static const unsigned char test_mac[1][16] =
}
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -517,7 +476,7 @@ int mbedtls_chachapoly_self_test( int verbose )
{
mbedtls_chachapoly_context ctx;
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output[200];
unsigned char mac[16];
diff --git a/thirdparty/mbedtls/library/check_crypto_config.h b/thirdparty/mbedtls/library/check_crypto_config.h
new file mode 100644
index 0000000000..d7ad16a617
--- /dev/null
+++ b/thirdparty/mbedtls/library/check_crypto_config.h
@@ -0,0 +1,91 @@
+/**
+ * \file check_crypto_config.h
+ *
+ * \brief Consistency checks for PSA configuration options
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * It is recommended to include this file from your crypto_config.h
+ * in order to catch dependency issues early.
+ */
+
+#ifndef MBEDTLS_CHECK_CRYPTO_CONFIG_H
+#define MBEDTLS_CHECK_CRYPTO_CONFIG_H
+
+#if defined(PSA_WANT_ALG_CCM) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) )
+#error "PSA_WANT_ALG_CCM defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_CMAC) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) || \
+ defined(PSA_WANT_KEY_TYPE_DES) )
+#error "PSA_WANT_ALG_CMAC defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_DETERMINISTIC_ECDSA) && \
+ !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_DETERMINISTIC_ECDSA defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_ECDSA) && \
+ !( defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_ECDSA defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_GCM) && \
+ !( defined(PSA_WANT_KEY_TYPE_AES) || \
+ defined(PSA_WANT_KEY_TYPE_CAMELLIA) )
+#error "PSA_WANT_ALG_GCM defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PKCS1V15_CRYPT) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PKCS1V15_CRYPT defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PKCS1V15_SIGN) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PKCS1V15_SIGN defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_OAEP) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_OAEP defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_ALG_RSA_PSS) && \
+ !( defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) || \
+ defined(PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY) )
+#error "PSA_WANT_ALG_RSA_PSS defined, but not all prerequisites"
+#endif
+
+#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) && \
+ !defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)
+#error "PSA_WANT_KEY_TYPE_ECC_KEY_PAIR defined, but not all prerequisites"
+#endif
+
+#endif /* MBEDTLS_CHECK_CRYPTO_CONFIG_H */
diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c
index 4ea0221f4d..4ec40d2cac 100644
--- a/thirdparty/mbedtls/library/cipher.c
+++ b/thirdparty/mbedtls/library/cipher.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,40 +19,17 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher.h"
#include "mbedtls/cipher_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
#include <stdlib.h>
#include <string.h>
@@ -83,6 +54,15 @@
#include "mbedtls/cmac.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -95,26 +75,6 @@
#define CIPHER_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C)
-/* Compare the contents of two buffers in constant time.
- * Returns 0 if the contents are bitwise identical, otherwise returns
- * a non-zero value.
- * This is currently only used by GCM and ChaCha20+Poly1305.
- */
-static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len )
-{
- const unsigned char *p1 = (const unsigned char*) v1;
- const unsigned char *p2 = (const unsigned char*) v2;
- size_t i;
- unsigned char diff;
-
- for( diff = 0, i = 0; i < len; i++ )
- diff |= p1[i] ^ p2[i];
-
- return( (int)diff );
-}
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */
-
static int supported_init = 0;
const int *mbedtls_cipher_list( void )
@@ -138,7 +98,8 @@ const int *mbedtls_cipher_list( void )
return( mbedtls_cipher_supported );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type(
+ const mbedtls_cipher_type_t cipher_type )
{
const mbedtls_cipher_definition_t *def;
@@ -149,7 +110,8 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher
return( NULL );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string(
+ const char *cipher_name )
{
const mbedtls_cipher_definition_t *def;
@@ -163,9 +125,10 @@ const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher
return( NULL );
}
-const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id,
- int key_bitlen,
- const mbedtls_cipher_mode_t mode )
+const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values(
+ const mbedtls_cipher_id_t cipher_id,
+ int key_bitlen,
+ const mbedtls_cipher_mode_t mode )
{
const mbedtls_cipher_definition_t *def;
@@ -189,6 +152,29 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
if( ctx == NULL )
return;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ if( ctx->cipher_ctx != NULL )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ if( cipher_psa->slot_state == MBEDTLS_CIPHER_PSA_KEY_OWNED )
+ {
+ /* xxx_free() doesn't allow to return failures. */
+ (void) psa_destroy_key( cipher_psa->slot );
+ }
+
+ mbedtls_platform_zeroize( cipher_psa, sizeof( *cipher_psa ) );
+ mbedtls_free( cipher_psa );
+ }
+
+ mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
+ return;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_CMAC_C)
if( ctx->cmac_ctx )
{
@@ -204,7 +190,8 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
mbedtls_platform_zeroize( ctx, sizeof(mbedtls_cipher_context_t) );
}
-int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info )
+int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info )
{
CIPHER_VALIDATE_RET( ctx != NULL );
if( cipher_info == NULL )
@@ -231,6 +218,38 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_cipher_setup_psa( mbedtls_cipher_context_t *ctx,
+ const mbedtls_cipher_info_t *cipher_info,
+ size_t taglen )
+{
+ psa_algorithm_t alg;
+ mbedtls_cipher_context_psa *cipher_psa;
+
+ if( NULL == cipher_info || NULL == ctx )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Check that the underlying cipher mode and cipher type are
+ * supported by the underlying PSA Crypto implementation. */
+ alg = mbedtls_psa_translate_cipher_mode( cipher_info->mode, taglen );
+ if( alg == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ if( mbedtls_psa_translate_cipher_type( cipher_info->type ) == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+
+ cipher_psa = mbedtls_calloc( 1, sizeof(mbedtls_cipher_context_psa ) );
+ if( cipher_psa == NULL )
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+ cipher_psa->alg = alg;
+ ctx->cipher_ctx = cipher_psa;
+ ctx->cipher_info = cipher_info;
+ ctx->psa_enabled = 1;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
const unsigned char *key,
int key_bitlen,
@@ -243,6 +262,64 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ size_t const key_bytelen = ( (size_t) key_bitlen + 7 ) / 8;
+
+ psa_status_t status;
+ psa_key_type_t key_type;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ /* PSA Crypto API only accepts byte-aligned keys. */
+ if( key_bitlen % 8 != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* Don't allow keys to be set multiple times. */
+ if( cipher_psa->slot_state != MBEDTLS_CIPHER_PSA_KEY_UNSET )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ key_type = mbedtls_psa_translate_cipher_type(
+ ctx->cipher_info->type );
+ if( key_type == 0 )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ psa_set_key_type( &attributes, key_type );
+
+ /* Mbed TLS' cipher layer doesn't enforce the mode of operation
+ * (encrypt vs. decrypt): it is possible to setup a key for encryption
+ * and use it for AEAD decryption. Until tests relying on this
+ * are changed, allow any usage in PSA. */
+ psa_set_key_usage_flags( &attributes,
+ /* mbedtls_psa_translate_cipher_operation( operation ); */
+ PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT );
+ psa_set_key_algorithm( &attributes, cipher_psa->alg );
+
+ status = psa_import_key( &attributes, key, key_bytelen,
+ &cipher_psa->slot );
+ switch( status )
+ {
+ case PSA_SUCCESS:
+ break;
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+ case PSA_ERROR_NOT_SUPPORTED:
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ default:
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+ }
+ /* Indicate that we own the key slot and need to
+ * destroy it in mbedtls_cipher_free(). */
+ cipher_psa->slot_state = MBEDTLS_CIPHER_PSA_KEY_OWNED;
+
+ ctx->key_bitlen = key_bitlen;
+ ctx->operation = operation;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 &&
(int) ctx->cipher_info->key_bitlen != key_bitlen )
{
@@ -281,6 +358,15 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx,
CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* avoid buffer overflow in ctx->iv */
if( iv_len > MBEDTLS_MAX_IV_LENGTH )
@@ -324,6 +410,15 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx )
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* We don't support resetting PSA-based
+ * cipher contexts, yet. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
ctx->unprocessed_len = 0;
return( 0 );
@@ -338,6 +433,16 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
@@ -374,7 +479,7 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx,
int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input,
size_t ilen, unsigned char *output, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t block_size;
CIPHER_VALIDATE_RET( ctx != NULL );
@@ -384,6 +489,16 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
*olen = 0;
block_size = mbedtls_cipher_get_block_size( ctx );
if ( 0 == block_size )
@@ -787,6 +902,16 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx,
if( ctx->cipher_info == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
*olen = 0;
if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode ||
@@ -879,6 +1004,19 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto knows about CBC padding
+ * schemes, we currently don't make them
+ * accessible through the cipher layer. */
+ if( mode != MBEDTLS_PADDING_NONE )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
switch( mode )
{
#if defined(MBEDTLS_CIPHER_PADDING_PKCS7)
@@ -930,6 +1068,16 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
if( MBEDTLS_ENCRYPT != ctx->operation )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
return( mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
@@ -943,8 +1091,8 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx,
if ( tag_len != 16U )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- tag ) );
+ return( mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ) );
}
#endif
@@ -955,7 +1103,7 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
const unsigned char *tag, size_t tag_len )
{
unsigned char check_tag[16];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
CIPHER_VALIDATE_RET( ctx != NULL );
CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
@@ -967,6 +1115,16 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* While PSA Crypto has an API for multipart
+ * operations, we currently don't make it
+ * accessible through the cipher layer. */
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/* Status to return on a non-authenticated algorithm. It would make sense
* to return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT or perhaps
* MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA, but at the time I write this our
@@ -979,14 +1137,15 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
if( tag_len > sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx,
- check_tag, tag_len ) ) )
+ if( 0 != ( ret = mbedtls_gcm_finish(
+ (mbedtls_gcm_context *) ctx->cipher_ctx,
+ check_tag, tag_len ) ) )
{
return( ret );
}
/* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
goto exit;
@@ -1001,15 +1160,15 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx,
if ( tag_len != sizeof( check_tag ) )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
- ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx,
- check_tag );
+ ret = mbedtls_chachapoly_finish(
+ (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag );
if ( ret != 0 )
{
return( ret );
}
/* Check the tag in "constant-time" */
- if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 )
+ if( mbedtls_ct_memcmp( tag, check_tag, tag_len ) != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
goto exit;
@@ -1031,7 +1190,7 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t finish_olen;
CIPHER_VALIDATE_RET( ctx != NULL );
@@ -1040,16 +1199,79 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
CIPHER_VALIDATE_RET( output != NULL );
CIPHER_VALIDATE_RET( olen != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+ psa_cipher_operation_t cipher_op = PSA_CIPHER_OPERATION_INIT;
+ size_t part_len;
+
+ if( ctx->operation == MBEDTLS_DECRYPT )
+ {
+ status = psa_cipher_decrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else if( ctx->operation == MBEDTLS_ENCRYPT )
+ {
+ status = psa_cipher_encrypt_setup( &cipher_op,
+ cipher_psa->slot,
+ cipher_psa->alg );
+ }
+ else
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ /* In the following, we can immediately return on an error,
+ * because the PSA Crypto API guarantees that cipher operations
+ * are terminated by unsuccessful calls to psa_cipher_update(),
+ * and by any call to psa_cipher_finish(). */
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ if( ctx->cipher_info->mode != MBEDTLS_MODE_ECB )
+ {
+ status = psa_cipher_set_iv( &cipher_op, iv, iv_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+ }
+
+ status = psa_cipher_update( &cipher_op,
+ input, ilen,
+ output, ilen, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ status = psa_cipher_finish( &cipher_op,
+ output + *olen, ilen - *olen,
+ &part_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen += part_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
return( ret );
if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
return( ret );
- if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_update( ctx, input, ilen,
+ output, olen ) ) != 0 )
return( ret );
- if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_finish( ctx, output + *olen,
+ &finish_olen ) ) != 0 )
return( ret );
*olen += finish_olen;
@@ -1059,30 +1281,55 @@ int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CIPHER_MODE_AEAD)
/*
- * Packet-oriented encryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_encrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( output == NULL || tag != output + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_encrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen,
+ output, ilen + tag_len, olen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ *olen -= tag_len;
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
*olen = ilen;
- return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen,
- iv, iv_len, ad, ad_len, input, output,
- tag_len, tag ) );
+ return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT,
+ ilen, iv, iv_len, ad, ad_len,
+ input, output, tag_len, tag ) );
}
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CCM_C)
@@ -1114,27 +1361,53 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
}
/*
- * Packet-oriented decryption for AEAD modes
+ * Packet-oriented encryption for AEAD modes: internal function shared by
+ * mbedtls_cipher_auth_encrypt() and mbedtls_cipher_auth_encrypt_ext().
*/
-int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+static int mbedtls_cipher_aead_decrypt( mbedtls_cipher_context_t *ctx,
const unsigned char *iv, size_t iv_len,
const unsigned char *ad, size_t ad_len,
const unsigned char *input, size_t ilen,
unsigned char *output, size_t *olen,
const unsigned char *tag, size_t tag_len )
{
- CIPHER_VALIDATE_RET( ctx != NULL );
- CIPHER_VALIDATE_RET( iv != NULL );
- CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
- CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
- CIPHER_VALIDATE_RET( output != NULL );
- CIPHER_VALIDATE_RET( olen != NULL );
- CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ctx->psa_enabled == 1 )
+ {
+ /* As in the non-PSA case, we don't check that
+ * a key has been set. If not, the key slot will
+ * still be in its default state of 0, which is
+ * guaranteed to be invalid, hence the PSA-call
+ * below will gracefully fail. */
+ mbedtls_cipher_context_psa * const cipher_psa =
+ (mbedtls_cipher_context_psa *) ctx->cipher_ctx;
+
+ psa_status_t status;
+
+ /* PSA Crypto API always writes the authentication tag
+ * at the end of the encrypted message. */
+ if( input == NULL || tag != input + ilen )
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+
+ status = psa_aead_decrypt( cipher_psa->slot,
+ cipher_psa->alg,
+ iv, iv_len,
+ ad, ad_len,
+ input, ilen + tag_len,
+ output, ilen, olen );
+ if( status == PSA_ERROR_INVALID_SIGNATURE )
+ return( MBEDTLS_ERR_CIPHER_AUTH_FAILED );
+ else if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED );
+
+ return( 0 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_GCM_C)
if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen;
ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen,
@@ -1150,7 +1423,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CCM_C)
if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
*olen = ilen;
ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen,
@@ -1166,7 +1439,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
#if defined(MBEDTLS_CHACHAPOLY_C)
if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* ChachaPoly has fixed length nonce and MAC (tag) */
if ( ( iv_len != ctx->cipher_info->iv_size ) ||
@@ -1188,6 +1461,166 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+/*
+ * Packet-oriented encryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+
+/*
+ * Packet-oriented decryption for AEAD modes: public legacy function.
+ */
+int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t *olen,
+ const unsigned char *tag, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+ CIPHER_VALIDATE_RET( tag_len == 0 || tag != NULL );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ tag, tag_len ) );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+#if defined(MBEDTLS_CIPHER_MODE_AEAD) || defined(MBEDTLS_NIST_KW_C)
+/*
+ * Packet-oriented encryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_encrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_NIST_KW_C)
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_wrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( output_len < ilen + tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ int ret = mbedtls_cipher_aead_encrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen, output, olen,
+ output + ilen, tag_len );
+ *olen += tag_len;
+ return( ret );
+#else
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+
+/*
+ * Packet-oriented decryption for AEAD/NIST_KW: public function.
+ */
+int mbedtls_cipher_auth_decrypt_ext( mbedtls_cipher_context_t *ctx,
+ const unsigned char *iv, size_t iv_len,
+ const unsigned char *ad, size_t ad_len,
+ const unsigned char *input, size_t ilen,
+ unsigned char *output, size_t output_len,
+ size_t *olen, size_t tag_len )
+{
+ CIPHER_VALIDATE_RET( ctx != NULL );
+ CIPHER_VALIDATE_RET( iv_len == 0 || iv != NULL );
+ CIPHER_VALIDATE_RET( ad_len == 0 || ad != NULL );
+ CIPHER_VALIDATE_RET( ilen == 0 || input != NULL );
+ CIPHER_VALIDATE_RET( output_len == 0 || output != NULL );
+ CIPHER_VALIDATE_RET( olen != NULL );
+
+#if defined(MBEDTLS_NIST_KW_C)
+ if(
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ctx->psa_enabled == 0 &&
+#endif
+ ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ||
+ MBEDTLS_MODE_KWP == ctx->cipher_info->mode ) )
+ {
+ mbedtls_nist_kw_mode_t mode = ( MBEDTLS_MODE_KW == ctx->cipher_info->mode ) ?
+ MBEDTLS_KW_MODE_KW : MBEDTLS_KW_MODE_KWP;
+
+ /* There is no iv, tag or ad associated with KW and KWP,
+ * so these length should be 0 as documented. */
+ if( iv_len != 0 || tag_len != 0 || ad_len != 0 )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ (void) iv;
+ (void) ad;
+
+ return( mbedtls_nist_kw_unwrap( ctx->cipher_ctx, mode, input, ilen,
+ output, olen, output_len ) );
+ }
+#endif /* MBEDTLS_NIST_KW_C */
+
+#if defined(MBEDTLS_CIPHER_MODE_AEAD)
+ /* AEAD case: check length before passing on to shared function */
+ if( ilen < tag_len || output_len < ilen - tag_len )
+ return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+
+ return( mbedtls_cipher_aead_decrypt( ctx, iv, iv_len, ad, ad_len,
+ input, ilen - tag_len, output, olen,
+ input + ilen - tag_len, tag_len ) );
+#else
+ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_CIPHER_MODE_AEAD */
+}
+#endif /* MBEDTLS_CIPHER_MODE_AEAD || MBEDTLS_NIST_KW_C */
+
#endif /* MBEDTLS_CIPHER_C */
diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c
index 5973ca6ba2..57eb3cb67f 100644
--- a/thirdparty/mbedtls/library/cipher_wrap.c
+++ b/thirdparty/mbedtls/library/cipher_wrap.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,38 +19,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CIPHER_C)
#include "mbedtls/cipher_internal.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_CHACHAPOLY_C)
#include "mbedtls/chachapoly.h"
@@ -98,6 +68,10 @@
#include "mbedtls/ccm.h"
#endif
+#if defined(MBEDTLS_NIST_KW_C)
+#include "mbedtls/nist_kw.h"
+#endif
+
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
#include <string.h>
#endif
@@ -1937,7 +1911,7 @@ static int chacha20_stream_wrap( void *ctx, size_t length,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_chacha20_update( ctx, length, input, output );
if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA )
@@ -2144,6 +2118,131 @@ static const mbedtls_cipher_info_t null_cipher_info = {
};
#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */
+#if defined(MBEDTLS_NIST_KW_C)
+static void *kw_ctx_alloc( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_nist_kw_context ) );
+
+ if( ctx != NULL )
+ mbedtls_nist_kw_init( (mbedtls_nist_kw_context *) ctx );
+
+ return( ctx );
+}
+
+static void kw_ctx_free( void *ctx )
+{
+ mbedtls_nist_kw_free( ctx );
+ mbedtls_free( ctx );
+}
+
+static int kw_aes_setkey_wrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 1 );
+}
+
+static int kw_aes_setkey_unwrap( void *ctx, const unsigned char *key,
+ unsigned int key_bitlen )
+{
+ return mbedtls_nist_kw_setkey( (mbedtls_nist_kw_context *) ctx,
+ MBEDTLS_CIPHER_ID_AES, key, key_bitlen, 0 );
+}
+
+static const mbedtls_cipher_base_t kw_aes_info = {
+ MBEDTLS_CIPHER_ID_AES,
+ NULL,
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+ NULL,
+#endif
+#if defined(MBEDTLS_CIPHER_MODE_STREAM)
+ NULL,
+#endif
+ kw_aes_setkey_wrap,
+ kw_aes_setkey_unwrap,
+ kw_ctx_alloc,
+ kw_ctx_free,
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_128_KW,
+ MBEDTLS_MODE_KW,
+ 128,
+ "AES-128-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_192_KW,
+ MBEDTLS_MODE_KW,
+ 192,
+ "AES-192-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kw_info = {
+ MBEDTLS_CIPHER_AES_256_KW,
+ MBEDTLS_MODE_KW,
+ 256,
+ "AES-256-KW",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_128_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_128_KWP,
+ MBEDTLS_MODE_KWP,
+ 128,
+ "AES-128-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_192_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_192_KWP,
+ MBEDTLS_MODE_KWP,
+ 192,
+ "AES-192-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+
+static const mbedtls_cipher_info_t aes_256_nist_kwp_info = {
+ MBEDTLS_CIPHER_AES_256_KWP,
+ MBEDTLS_MODE_KWP,
+ 256,
+ "AES-256-KWP",
+ 0,
+ 0,
+ 16,
+ &kw_aes_info
+};
+#endif /* MBEDTLS_NIST_KW_C */
+
const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{
#if defined(MBEDTLS_AES_C)
@@ -2284,6 +2383,15 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info },
#endif
+#if defined(MBEDTLS_NIST_KW_C)
+ { MBEDTLS_CIPHER_AES_128_KW, &aes_128_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_192_KW, &aes_192_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_256_KW, &aes_256_nist_kw_info },
+ { MBEDTLS_CIPHER_AES_128_KWP, &aes_128_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_192_KWP, &aes_192_nist_kwp_info },
+ { MBEDTLS_CIPHER_AES_256_KWP, &aes_256_nist_kwp_info },
+#endif
+
#if defined(MBEDTLS_CIPHER_NULL_CIPHER)
{ MBEDTLS_CIPHER_NULL, &null_cipher_info },
#endif /* MBEDTLS_CIPHER_NULL_CIPHER */
@@ -2291,7 +2399,8 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] =
{ MBEDTLS_CIPHER_NONE, NULL }
};
-#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0]
+#define NUM_CIPHERS ( sizeof(mbedtls_cipher_definitions) / \
+ sizeof(mbedtls_cipher_definitions[0]) )
int mbedtls_cipher_supported[NUM_CIPHERS];
#endif /* MBEDTLS_CIPHER_C */
diff --git a/thirdparty/mbedtls/library/cmac.c b/thirdparty/mbedtls/library/cmac.c
index 409f67958e..3cc49d10cc 100644
--- a/thirdparty/mbedtls/library/cmac.c
+++ b/thirdparty/mbedtls/library/cmac.c
@@ -4,13 +4,7 @@
* \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,27 +17,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -65,32 +38,17 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CMAC_C)
#include "mbedtls/cmac.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform.h"
#include <string.h>
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#if defined(MBEDTLS_SELF_TEST)
-#include <stdio.h>
-#define mbedtls_printf printf
-#endif /* MBEDTLS_SELF_TEST */
-#endif /* MBEDTLS_PLATFORM_C */
-
#if !defined(MBEDTLS_CMAC_ALT) || defined(MBEDTLS_SELF_TEST)
/*
@@ -161,7 +119,7 @@ static int cmac_multiply_by_u( unsigned char *output,
static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx,
unsigned char* K1, unsigned char* K2 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX];
size_t olen, block_size;
@@ -340,7 +298,7 @@ int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx,
unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX];
unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen, block_size;
if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
@@ -418,7 +376,7 @@ int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
unsigned char *output )
{
mbedtls_cipher_context_t ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@@ -452,7 +410,7 @@ int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
const unsigned char *input, size_t in_len,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
@@ -808,7 +766,7 @@ static int cmac_test_subkeys( int verbose,
for( i = 0; i < num_tests; i++ )
{
if( verbose != 0 )
- mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 );
+ mbedtls_printf( " %s CMAC subkey #%d: ", testname, i + 1 );
mbedtls_cipher_init( &ctx );
@@ -823,6 +781,18 @@ static int cmac_test_subkeys( int verbose,
if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits,
MBEDTLS_ENCRYPT ) ) != 0 )
{
+ /* When CMAC is implemented by an alternative implementation, or
+ * the underlying primitive itself is implemented alternatively,
+ * AES-192 may be unavailable. This should not cause the selftest
+ * function to fail. */
+ if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
+ ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
+ cipher_type == MBEDTLS_CIPHER_AES_192_ECB ) {
+ if( verbose != 0 )
+ mbedtls_printf( "skipped\n" );
+ goto next_test;
+ }
+
if( verbose != 0 )
mbedtls_printf( "test execution failed\n" );
@@ -850,6 +820,7 @@ static int cmac_test_subkeys( int verbose,
if( verbose != 0 )
mbedtls_printf( "passed\n" );
+next_test:
mbedtls_cipher_free( &ctx );
}
@@ -889,11 +860,24 @@ static int cmac_test_wth_cipher( int verbose,
for( i = 0; i < num_tests; i++ )
{
if( verbose != 0 )
- mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 );
+ mbedtls_printf( " %s CMAC #%d: ", testname, i + 1 );
if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages,
message_lengths[i], output ) ) != 0 )
{
+ /* When CMAC is implemented by an alternative implementation, or
+ * the underlying primitive itself is implemented alternatively,
+ * AES-192 and/or 3DES may be unavailable. This should not cause
+ * the selftest function to fail. */
+ if( ( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED ||
+ ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ) &&
+ ( cipher_type == MBEDTLS_CIPHER_AES_192_ECB ||
+ cipher_type == MBEDTLS_CIPHER_DES_EDE3_ECB ) ) {
+ if( verbose != 0 )
+ mbedtls_printf( "skipped\n" );
+ continue;
+ }
+
if( verbose != 0 )
mbedtls_printf( "failed\n" );
goto exit;
@@ -919,12 +903,12 @@ exit:
static int test_aes128_cmac_prf( int verbose )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output[MBEDTLS_AES_BLOCK_SIZE];
for( i = 0; i < NB_PRF_TESTS; i++ )
{
- mbedtls_printf( " AES CMAC 128 PRF #%u: ", i );
+ mbedtls_printf( " AES CMAC 128 PRF #%d: ", i );
ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output );
if( ret != 0 ||
memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 )
@@ -946,7 +930,7 @@ static int test_aes128_cmac_prf( int verbose )
int mbedtls_cmac_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_AES_C)
/* AES-128 */
diff --git a/thirdparty/mbedtls/library/common.h b/thirdparty/mbedtls/library/common.h
new file mode 100644
index 0000000000..c06472418d
--- /dev/null
+++ b/thirdparty/mbedtls/library/common.h
@@ -0,0 +1,305 @@
+/**
+ * \file common.h
+ *
+ * \brief Utility macros for internal use in the library
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_LIBRARY_COMMON_H
+#define MBEDTLS_LIBRARY_COMMON_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#else
+#include "mbedtls/config.h"
+#endif
+
+#include <stdint.h>
+
+/** Helper to define a function as static except when building invasive tests.
+ *
+ * If a function is only used inside its own source file and should be
+ * declared `static` to allow the compiler to optimize for code size,
+ * but that function has unit tests, define it with
+ * ```
+ * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
+ * ```
+ * and declare it in a header in the `library/` directory with
+ * ```
+ * #if defined(MBEDTLS_TEST_HOOKS)
+ * int mbedtls_foo(...);
+ * #endif
+ * ```
+ */
+#if defined(MBEDTLS_TEST_HOOKS)
+#define MBEDTLS_STATIC_TESTABLE
+#else
+#define MBEDTLS_STATIC_TESTABLE static
+#endif
+
+/** Byte Reading Macros
+ *
+ * Given a multi-byte integer \p x, MBEDTLS_BYTE_n retrieves the n-th
+ * byte from x, where byte 0 is the least significant byte.
+ */
+#define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) )
+#define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) )
+#define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) )
+#define MBEDTLS_BYTE_3( x ) ( (uint8_t) ( ( ( x ) >> 24 ) & 0xff ) )
+#define MBEDTLS_BYTE_4( x ) ( (uint8_t) ( ( ( x ) >> 32 ) & 0xff ) )
+#define MBEDTLS_BYTE_5( x ) ( (uint8_t) ( ( ( x ) >> 40 ) & 0xff ) )
+#define MBEDTLS_BYTE_6( x ) ( (uint8_t) ( ( ( x ) >> 48 ) & 0xff ) )
+#define MBEDTLS_BYTE_7( x ) ( (uint8_t) ( ( ( x ) >> 56 ) & 0xff ) )
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the four bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the four bytes to build the 32 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_BE
+#define MBEDTLS_GET_UINT32_BE( data , offset ) \
+ ( \
+ ( (uint32_t) ( data )[( offset ) ] << 24 ) \
+ | ( (uint32_t) ( data )[( offset ) + 1] << 16 ) \
+ | ( (uint32_t) ( data )[( offset ) + 2] << 8 ) \
+ | ( (uint32_t) ( data )[( offset ) + 3] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in big-endian order.
+ *
+ * \param n 32 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 32
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_BE
+#define MBEDTLS_PUT_UINT32_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 32 bits integer corresponding to four bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the four bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the four bytes to build the 32 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT32_LE
+#define MBEDTLS_GET_UINT32_LE( data, offset ) \
+ ( \
+ ( (uint32_t) ( data )[( offset ) ] ) \
+ | ( (uint32_t) ( data )[( offset ) + 1] << 8 ) \
+ | ( (uint32_t) ( data )[( offset ) + 2] << 16 ) \
+ | ( (uint32_t) ( data )[( offset ) + 3] << 24 ) \
+ )
+#endif
+
+/**
+ * Put in memory a 32 bits unsigned integer in little-endian order.
+ *
+ * \param n 32 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 32
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 32 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT32_LE
+#define MBEDTLS_PUT_UINT32_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the two bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the two bytes to build the 16 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_LE
+#define MBEDTLS_GET_UINT16_LE( data, offset ) \
+ ( \
+ ( (uint16_t) ( data )[( offset ) ] ) \
+ | ( (uint16_t) ( data )[( offset ) + 1] << 8 ) \
+ )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in little-endian order.
+ *
+ * \param n 16 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 16
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_LE
+#define MBEDTLS_PUT_UINT16_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 16 bits integer corresponding to two bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the two bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the two bytes to build the 16 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT16_BE
+#define MBEDTLS_GET_UINT16_BE( data, offset ) \
+ ( \
+ ( (uint16_t) ( data )[( offset ) ] << 8 ) \
+ | ( (uint16_t) ( data )[( offset ) + 1] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 16 bits unsigned integer in big-endian order.
+ *
+ * \param n 16 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 16
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 16 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT16_BE
+#define MBEDTLS_PUT_UINT16_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * big-endian order (MSB first).
+ *
+ * \param data Base address of the memory to get the eight bytes from.
+ * \param offset Offset from \p base of the first and most significant
+ * byte of the eight bytes to build the 64 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_BE
+#define MBEDTLS_GET_UINT64_BE( data, offset ) \
+ ( \
+ ( (uint64_t) ( data )[( offset ) ] << 56 ) \
+ | ( (uint64_t) ( data )[( offset ) + 1] << 48 ) \
+ | ( (uint64_t) ( data )[( offset ) + 2] << 40 ) \
+ | ( (uint64_t) ( data )[( offset ) + 3] << 32 ) \
+ | ( (uint64_t) ( data )[( offset ) + 4] << 24 ) \
+ | ( (uint64_t) ( data )[( offset ) + 5] << 16 ) \
+ | ( (uint64_t) ( data )[( offset ) + 6] << 8 ) \
+ | ( (uint64_t) ( data )[( offset ) + 7] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in big-endian order.
+ *
+ * \param n 64 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 64
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the most significant
+ * byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_BE
+#define MBEDTLS_PUT_UINT64_BE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_7( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_6( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_5( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_4( n ); \
+ ( data )[( offset ) + 4] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 5] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 6] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 7] = MBEDTLS_BYTE_0( n ); \
+}
+#endif
+
+/**
+ * Get the unsigned 64 bits integer corresponding to eight bytes in
+ * little-endian order (LSB first).
+ *
+ * \param data Base address of the memory to get the eight bytes from.
+ * \param offset Offset from \p base of the first and least significant
+ * byte of the eight bytes to build the 64 bits unsigned
+ * integer from.
+ */
+#ifndef MBEDTLS_GET_UINT64_LE
+#define MBEDTLS_GET_UINT64_LE( data, offset ) \
+ ( \
+ ( (uint64_t) ( data )[( offset ) + 7] << 56 ) \
+ | ( (uint64_t) ( data )[( offset ) + 6] << 48 ) \
+ | ( (uint64_t) ( data )[( offset ) + 5] << 40 ) \
+ | ( (uint64_t) ( data )[( offset ) + 4] << 32 ) \
+ | ( (uint64_t) ( data )[( offset ) + 3] << 24 ) \
+ | ( (uint64_t) ( data )[( offset ) + 2] << 16 ) \
+ | ( (uint64_t) ( data )[( offset ) + 1] << 8 ) \
+ | ( (uint64_t) ( data )[( offset ) ] ) \
+ )
+#endif
+
+/**
+ * Put in memory a 64 bits unsigned integer in little-endian order.
+ *
+ * \param n 64 bits unsigned integer to put in memory.
+ * \param data Base address of the memory where to put the 64
+ * bits unsigned integer in.
+ * \param offset Offset from \p base where to put the least significant
+ * byte of the 64 bits unsigned integer \p n.
+ */
+#ifndef MBEDTLS_PUT_UINT64_LE
+#define MBEDTLS_PUT_UINT64_LE( n, data, offset ) \
+{ \
+ ( data )[( offset ) ] = MBEDTLS_BYTE_0( n ); \
+ ( data )[( offset ) + 1] = MBEDTLS_BYTE_1( n ); \
+ ( data )[( offset ) + 2] = MBEDTLS_BYTE_2( n ); \
+ ( data )[( offset ) + 3] = MBEDTLS_BYTE_3( n ); \
+ ( data )[( offset ) + 4] = MBEDTLS_BYTE_4( n ); \
+ ( data )[( offset ) + 5] = MBEDTLS_BYTE_5( n ); \
+ ( data )[( offset ) + 6] = MBEDTLS_BYTE_6( n ); \
+ ( data )[( offset ) + 7] = MBEDTLS_BYTE_7( n ); \
+}
+#endif
+
+#endif /* MBEDTLS_LIBRARY_COMMON_H */
diff --git a/thirdparty/mbedtls/library/constant_time.c b/thirdparty/mbedtls/library/constant_time.c
new file mode 100644
index 0000000000..18f1b20daa
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time.c
@@ -0,0 +1,819 @@
+/**
+ * Constant-time functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ /*
+ * The following functions are implemented without using comparison operators, as those
+ * might be translated to branches by some compilers on some platforms.
+ */
+
+#include "common.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+#include "mbedtls/rsa.h"
+#endif
+
+#if defined(MBEDTLS_BASE64_C)
+#include "constant_time_invasive.h"
+#endif
+
+#include <string.h>
+
+int mbedtls_ct_memcmp( const void *a,
+ const void *b,
+ size_t n )
+{
+ size_t i;
+ volatile const unsigned char *A = (volatile const unsigned char *) a;
+ volatile const unsigned char *B = (volatile const unsigned char *) b;
+ volatile unsigned char diff = 0;
+
+ for( i = 0; i < n; i++ )
+ {
+ /* Read volatile data in order before computing diff.
+ * This avoids IAR compiler warning:
+ * 'the order of volatile accesses is undefined ..' */
+ unsigned char x = A[i], y = B[i];
+ diff |= x ^ y;
+ }
+
+ return( (int)diff );
+}
+
+unsigned mbedtls_ct_uint_mask( unsigned value )
+{
+ /* MSVC has a warning about unary minus on unsigned, 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
+ return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+size_t mbedtls_ct_size_mask( size_t value )
+{
+ /* 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
+ return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value )
+{
+ /* MSVC has a warning about unary minus on unsigned, 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
+ return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "less than" comparison:
+ * - if \p x < \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return All-bits-one if \p x is less than \p y, otherwise zero.
+ */
+static size_t mbedtls_ct_size_mask_lt( size_t x,
+ size_t y )
+{
+ /* This has the most significant bit set if and only if x < y */
+ const size_t sub = x - y;
+
+ /* sub1 = (x < y) ? 1 : 0 */
+ const size_t sub1 = sub >> ( sizeof( sub ) * 8 - 1 );
+
+ /* mask = (x < y) ? 0xff... : 0x00... */
+ const size_t mask = mbedtls_ct_size_mask( sub1 );
+
+ return( mask );
+}
+
+size_t mbedtls_ct_size_mask_ge( size_t x,
+ size_t y )
+{
+ return( ~mbedtls_ct_size_mask_lt( x, y ) );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/* Return 0xff if low <= c <= high, 0 otherwise.
+ *
+ * Constant flow with respect to c.
+ */
+MBEDTLS_STATIC_TESTABLE
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+ unsigned char high,
+ unsigned char c )
+{
+ /* low_mask is: 0 if low <= c, 0x...ff if low > c */
+ unsigned low_mask = ( (unsigned) c - low ) >> 8;
+ /* high_mask is: 0 if c <= high, 0x...ff if c > high */
+ unsigned high_mask = ( (unsigned) high - c ) >> 8;
+ return( ~( low_mask | high_mask ) & 0xff );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+ size_t y )
+{
+ /* diff = 0 if x == y, non-zero otherwise */
+ const size_t diff = x ^ y;
+
+ /* 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 x != y */
+ const size_t diff_msb = ( diff | (size_t) -diff );
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+ /* diff1 = (x != y) ? 1 : 0 */
+ const unsigned diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
+
+ return( 1 ^ diff1 );
+}
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Constant-flow "greater than" comparison:
+ * return x > y
+ *
+ * This is equivalent to \p x > \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x greater than \p y, otherwise 0.
+ */
+static unsigned mbedtls_ct_size_gt( size_t x,
+ size_t y )
+{
+ /* Return the sign bit (1 for negative) of (y - x). */
+ return( ( y - x ) >> ( sizeof( size_t ) * 8 - 1 ) );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+ const mbedtls_mpi_uint y )
+{
+ mbedtls_mpi_uint ret;
+ mbedtls_mpi_uint cond;
+
+ /*
+ * Check if the most significant bits (MSB) of the operands are different.
+ */
+ cond = ( x ^ y );
+ /*
+ * If the MSB are the same then the difference x-y will be negative (and
+ * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
+ */
+ ret = ( x - y ) & ~cond;
+ /*
+ * If the MSB are different, then the operand with the MSB of 1 is the
+ * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
+ * the MSB of y is 0.)
+ */
+ ret |= y & cond;
+
+
+ ret = ret >> ( sizeof( mbedtls_mpi_uint ) * 8 - 1 );
+
+ return (unsigned) ret;
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+unsigned mbedtls_ct_uint_if( unsigned condition,
+ unsigned if1,
+ unsigned if0 )
+{
+ unsigned mask = mbedtls_ct_uint_mask( condition );
+ return( ( mask & if1 ) | (~mask & if0 ) );
+}
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Select between two sign values without branches.
+ *
+ * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
+ * operations in order to avoid branches.
+ *
+ * \note if1 and if0 must be either 1 or -1, otherwise the result
+ * is undefined.
+ *
+ * \param condition Condition to test.
+ * \param if1 The first sign; must be either +1 or -1.
+ * \param if0 The second sign; must be either +1 or -1.
+ *
+ * \return \c if1 if \p condition is nonzero, otherwise \c if0.
+ * */
+static int mbedtls_ct_cond_select_sign( unsigned char condition,
+ int if1,
+ int if0 )
+{
+ /* In order to avoid questions about what we can reasonably assume about
+ * the representations of signed integers, move everything to unsigned
+ * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
+ unsigned uif1 = if1 + 1;
+ unsigned uif0 = if0 + 1;
+
+ /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
+ const unsigned mask = condition << 1;
+
+ /* select uif1 or uif0 */
+ unsigned ur = ( uif0 & ~mask ) | ( uif1 & mask );
+
+ /* ur is now 0 or 2, convert back to -1 or +1 */
+ return( (int) ur - 1 );
+}
+
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+ mbedtls_mpi_uint *dest,
+ const mbedtls_mpi_uint *src,
+ unsigned char condition )
+{
+ size_t i;
+
+ /* 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
+
+ /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
+ const mbedtls_mpi_uint mask = -condition;
+
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#endif
+
+ for( i = 0; i < n; i++ )
+ dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value )
+{
+ unsigned char digit = 0;
+ /* For each range of values, if value is in that range, mask digit with
+ * the corresponding value. Since value can only be in a single range,
+ * only at most one masking will change digit. */
+ digit |= mbedtls_ct_uchar_mask_of_range( 0, 25, value ) & ( 'A' + value );
+ digit |= mbedtls_ct_uchar_mask_of_range( 26, 51, value ) & ( 'a' + value - 26 );
+ digit |= mbedtls_ct_uchar_mask_of_range( 52, 61, value ) & ( '0' + value - 52 );
+ digit |= mbedtls_ct_uchar_mask_of_range( 62, 62, value ) & '+';
+ digit |= mbedtls_ct_uchar_mask_of_range( 63, 63, value ) & '/';
+ return( digit );
+}
+
+signed char mbedtls_ct_base64_dec_value( unsigned char c )
+{
+ unsigned char val = 0;
+ /* For each range of digits, if c is in that range, mask val with
+ * the corresponding value. Since c can only be in a single range,
+ * only at most one masking will change val. Set val to one plus
+ * the desired value so that it stays 0 if c is in none of the ranges. */
+ val |= mbedtls_ct_uchar_mask_of_range( 'A', 'Z', c ) & ( c - 'A' + 0 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( 'a', 'z', c ) & ( c - 'a' + 26 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '0', '9', c ) & ( c - '0' + 52 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '+', '+', c ) & ( c - '+' + 62 + 1 );
+ val |= mbedtls_ct_uchar_mask_of_range( '/', '/', c ) & ( c - '/' + 63 + 1 );
+ /* At this point, val is 0 if c is an invalid digit and v+1 if c is
+ * a digit with the value v. */
+ return( val - 1 );
+}
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** Shift some data towards the left inside a buffer.
+ *
+ * `mbedtls_ct_mem_move_to_left(start, total, offset)` is functionally
+ * equivalent to
+ * ```
+ * memmove(start, start + offset, total - offset);
+ * memset(start + offset, 0, total - offset);
+ * ```
+ * but it strives to use a memory access pattern (and thus total timing)
+ * that does not depend on \p offset. This timing independence comes at
+ * the expense of performance.
+ *
+ * \param start Pointer to the start of the buffer.
+ * \param total Total size of the buffer.
+ * \param offset Offset from which to copy \p total - \p offset bytes.
+ */
+static void mbedtls_ct_mem_move_to_left( void *start,
+ size_t total,
+ size_t offset )
+{
+ volatile unsigned char *buf = start;
+ size_t i, n;
+ if( total == 0 )
+ return;
+ for( i = 0; i < total; i++ )
+ {
+ unsigned no_op = mbedtls_ct_size_gt( total - offset, i );
+ /* The first `total - offset` passes are a no-op. The last
+ * `offset` passes shift the data one byte to the left and
+ * zero out the last byte. */
+ for( n = 0; n < total - 1; n++ )
+ {
+ unsigned char current = buf[n];
+ unsigned char next = buf[n+1];
+ buf[n] = mbedtls_ct_uint_if( no_op, current, next );
+ }
+ buf[total-1] = mbedtls_ct_uint_if( no_op, buf[total-1], 0 );
+ }
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+ const unsigned char *src,
+ size_t len,
+ size_t c1,
+ size_t c2 )
+{
+ /* mask = c1 == c2 ? 0xff : 0x00 */
+ const size_t equal = mbedtls_ct_size_bool_eq( c1, c2 );
+ const unsigned char mask = (unsigned char) mbedtls_ct_size_mask( equal );
+
+ /* dest[i] = c1 == c2 ? src[i] : dest[i] */
+ for( size_t i = 0; i < len; i++ )
+ dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
+}
+
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+ const unsigned char *src,
+ size_t offset,
+ size_t offset_min,
+ size_t offset_max,
+ size_t len )
+{
+ size_t offsetval;
+
+ for( offsetval = offset_min; offsetval <= offset_max; offsetval++ )
+ {
+ mbedtls_ct_memcpy_if_eq( dest, src + offsetval, len,
+ offsetval, offset );
+ }
+}
+
+int mbedtls_ct_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_ERR_ERROR_CORRUPTION_DETECTED;
+
+ 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_ct_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 ) );
+ }
+
+ /* The context needs to finish() before it starts() again */
+ MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
+
+ /* 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 );
+}
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+#define MPI_VALIDATE_RET( cond ) \
+ MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
+
+/*
+ * Conditionally assign X = Y, without leaking information
+ * about whether the assignment was made or not.
+ * (Leaking information about the respective sizes of X and Y is ok however.)
+ */
+int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X,
+ const mbedtls_mpi *Y,
+ unsigned char assign )
+{
+ int ret = 0;
+ size_t i;
+ mbedtls_mpi_uint limb_mask;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+
+ /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
+ limb_mask = mbedtls_ct_mpi_uint_mask( assign );;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+
+ X->s = mbedtls_ct_cond_select_sign( assign, Y->s, X->s );
+
+ mbedtls_ct_mpi_uint_cond_assign( Y->n, X->p, Y->p, assign );
+
+ for( i = Y->n; i < X->n; i++ )
+ X->p[i] &= ~limb_mask;
+
+cleanup:
+ return( ret );
+}
+
+/*
+ * Conditionally swap X and Y, without leaking information
+ * about whether the swap was made or not.
+ * Here it is not ok to simply swap the pointers, which whould lead to
+ * different memory access patterns when X and Y are used afterwards.
+ */
+int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X,
+ mbedtls_mpi *Y,
+ unsigned char swap )
+{
+ int ret, s;
+ size_t i;
+ mbedtls_mpi_uint limb_mask;
+ mbedtls_mpi_uint tmp;
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+
+ if( X == Y )
+ return( 0 );
+
+ /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
+ limb_mask = mbedtls_ct_mpi_uint_mask( swap );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
+
+ s = X->s;
+ X->s = mbedtls_ct_cond_select_sign( swap, Y->s, X->s );
+ Y->s = mbedtls_ct_cond_select_sign( swap, s, Y->s );
+
+
+ for( i = 0; i < X->n; i++ )
+ {
+ tmp = X->p[i];
+ X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
+ Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
+ }
+
+cleanup:
+ return( ret );
+}
+
+/*
+ * Compare signed values in constant time
+ */
+int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X,
+ const mbedtls_mpi *Y,
+ unsigned *ret )
+{
+ size_t i;
+ /* The value of any of these variables is either 0 or 1 at all times. */
+ unsigned cond, done, X_is_negative, Y_is_negative;
+
+ MPI_VALIDATE_RET( X != NULL );
+ MPI_VALIDATE_RET( Y != NULL );
+ MPI_VALIDATE_RET( ret != NULL );
+
+ if( X->n != Y->n )
+ return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+
+ /*
+ * Set sign_N to 1 if N >= 0, 0 if N < 0.
+ * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
+ */
+ X_is_negative = ( X->s & 2 ) >> 1;
+ Y_is_negative = ( Y->s & 2 ) >> 1;
+
+ /*
+ * If the signs are different, then the positive operand is the bigger.
+ * That is if X is negative (X_is_negative == 1), then X < Y is true and it
+ * is false if X is positive (X_is_negative == 0).
+ */
+ cond = ( X_is_negative ^ Y_is_negative );
+ *ret = cond & X_is_negative;
+
+ /*
+ * This is a constant-time function. We might have the result, but we still
+ * need to go through the loop. Record if we have the result already.
+ */
+ done = cond;
+
+ for( i = X->n; i > 0; i-- )
+ {
+ /*
+ * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
+ * X and Y are negative.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( Y->p[i - 1], X->p[i - 1] );
+ *ret |= cond & ( 1 - done ) & X_is_negative;
+ done |= cond;
+
+ /*
+ * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
+ * X and Y are positive.
+ *
+ * Again even if we can make a decision, we just mark the result and
+ * the fact that we are done and continue looping.
+ */
+ cond = mbedtls_ct_mpi_uint_lt( X->p[i - 1], Y->p[i - 1] );
+ *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
+ done |= cond;
+ }
+
+ return( 0 );
+}
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+ unsigned char *input,
+ size_t ilen,
+ unsigned char *output,
+ size_t output_max_len,
+ size_t *olen )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i, plaintext_max_size;
+
+ /* The following variables take sensitive values: their value must
+ * not leak into the observable behavior of the function other than
+ * the designated outputs (output, olen, return value). Otherwise
+ * this would open the execution of the function to
+ * side-channel-based variants of the Bleichenbacher padding oracle
+ * attack. Potential side channels include overall timing, memory
+ * access patterns (especially visible to an adversary who has access
+ * to a shared memory cache), and branches (especially visible to
+ * an adversary who has access to a shared code cache or to a shared
+ * branch predictor). */
+ size_t pad_count = 0;
+ unsigned bad = 0;
+ unsigned char pad_done = 0;
+ size_t plaintext_size = 0;
+ unsigned output_too_large;
+
+ plaintext_max_size = ( output_max_len > ilen - 11 ) ? ilen - 11
+ : output_max_len;
+
+ /* Check and get padding length in constant time and constant
+ * memory trace. The first byte must be 0. */
+ bad |= input[0];
+
+ if( mode == MBEDTLS_RSA_PRIVATE )
+ {
+ /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
+ * where PS must be at least 8 nonzero bytes. */
+ bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
+
+ /* Read the whole buffer. Set pad_done to nonzero if we find
+ * the 0x00 byte and remember the padding length in pad_count. */
+ for( i = 2; i < ilen; i++ )
+ {
+ pad_done |= ((input[i] | (unsigned char)-input[i]) >> 7) ^ 1;
+ pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
+ }
+ }
+ else
+ {
+ /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
+ * where PS must be at least 8 bytes with the value 0xFF. */
+ bad |= input[1] ^ MBEDTLS_RSA_SIGN;
+
+ /* Read the whole buffer. Set pad_done to nonzero if we find
+ * the 0x00 byte and remember the padding length in pad_count.
+ * If there's a non-0xff byte in the padding, the padding is bad. */
+ for( i = 2; i < ilen; i++ )
+ {
+ pad_done |= mbedtls_ct_uint_if( input[i], 0, 1 );
+ pad_count += mbedtls_ct_uint_if( pad_done, 0, 1 );
+ bad |= mbedtls_ct_uint_if( pad_done, 0, input[i] ^ 0xFF );
+ }
+ }
+
+ /* If pad_done is still zero, there's no data, only unfinished padding. */
+ bad |= mbedtls_ct_uint_if( pad_done, 0, 1 );
+
+ /* There must be at least 8 bytes of padding. */
+ bad |= mbedtls_ct_size_gt( 8, pad_count );
+
+ /* If the padding is valid, set plaintext_size to the number of
+ * remaining bytes after stripping the padding. If the padding
+ * is invalid, avoid leaking this fact through the size of the
+ * output: use the maximum message size that fits in the output
+ * buffer. Do it without branches to avoid leaking the padding
+ * validity through timing. RSA keys are small enough that all the
+ * size_t values involved fit in unsigned int. */
+ plaintext_size = mbedtls_ct_uint_if(
+ bad, (unsigned) plaintext_max_size,
+ (unsigned) ( ilen - pad_count - 3 ) );
+
+ /* Set output_too_large to 0 if the plaintext fits in the output
+ * buffer and to 1 otherwise. */
+ output_too_large = mbedtls_ct_size_gt( plaintext_size,
+ plaintext_max_size );
+
+ /* Set ret without branches to avoid timing attacks. Return:
+ * - INVALID_PADDING if the padding is bad (bad != 0).
+ * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
+ * plaintext does not fit in the output buffer.
+ * - 0 if the padding is correct. */
+ ret = - (int) mbedtls_ct_uint_if(
+ bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
+ mbedtls_ct_uint_if( output_too_large,
+ - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
+ 0 ) );
+
+ /* If the padding is bad or the plaintext is too large, zero the
+ * data that we're about to copy to the output buffer.
+ * We need to copy the same amount of data
+ * from the same buffer whether the padding is good or not to
+ * avoid leaking the padding validity through overall timing or
+ * through memory or cache access patterns. */
+ bad = mbedtls_ct_uint_mask( bad | output_too_large );
+ for( i = 11; i < ilen; i++ )
+ input[i] &= ~bad;
+
+ /* If the plaintext is too large, truncate it to the buffer size.
+ * Copy anyway to avoid revealing the length through timing, because
+ * revealing the length is as bad as revealing the padding validity
+ * for a Bleichenbacher attack. */
+ plaintext_size = mbedtls_ct_uint_if( output_too_large,
+ (unsigned) plaintext_max_size,
+ (unsigned) plaintext_size );
+
+ /* Move the plaintext to the leftmost position where it can start in
+ * the working buffer, i.e. make it start plaintext_max_size from
+ * the end of the buffer. Do this with a memory access trace that
+ * does not depend on the plaintext size. After this move, the
+ * starting location of the plaintext is no longer sensitive
+ * information. */
+ mbedtls_ct_mem_move_to_left( input + ilen - plaintext_max_size,
+ plaintext_max_size,
+ plaintext_max_size - plaintext_size );
+
+ /* Finally copy the decrypted plaintext plus trailing zeros into the output
+ * buffer. If output_max_len is 0, then output may be an invalid pointer
+ * and the result of memcpy() would be undefined; prevent undefined
+ * behavior making sure to depend only on output_max_len (the size of the
+ * user-provided output buffer), which is independent from plaintext
+ * length, validity of padding, success of the decryption, and other
+ * secrets. */
+ if( output_max_len != 0 )
+ memcpy( output, input + ilen - plaintext_max_size, plaintext_max_size );
+
+ /* Report the amount of data we copied to the output buffer. In case
+ * of errors (bad padding or output too large), the value of *olen
+ * when this function returns is not specified. Making it equivalent
+ * to the good case limits the risks of leaking the padding validity. */
+ *olen = plaintext_size;
+
+ return( ret );
+}
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
diff --git a/thirdparty/mbedtls/library/constant_time_internal.h b/thirdparty/mbedtls/library/constant_time_internal.h
new file mode 100644
index 0000000000..bbb3a90670
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time_internal.h
@@ -0,0 +1,329 @@
+/**
+ * Constant-time functions
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
+#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_BIGNUM_C)
+#include "mbedtls/bignum.h"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C)
+#include "mbedtls/ssl_internal.h"
+#endif
+
+#include <stddef.h>
+
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (unsigned) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+unsigned mbedtls_ct_uint_mask( unsigned value );
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (size_t) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+size_t mbedtls_ct_size_mask( size_t value );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Turn a value into a mask:
+ * - if \p value == 0, return the all-bits 0 mask, aka 0
+ * - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param value The value to analyze.
+ *
+ * \return Zero if \p value is zero, otherwise all-bits-one.
+ */
+mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask( mbedtls_mpi_uint value );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Constant-flow mask generation for "greater or equal" comparison:
+ * - if \p x >= \p y, return all-bits 1, that is (size_t) -1
+ * - otherwise, return all bits 0, that is 0
+ *
+ * This function can be used to write constant-time code by replacing branches
+ * with bit operations using masks.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return All-bits-one if \p x is greater or equal than \p y,
+ * otherwise zero.
+ */
+size_t mbedtls_ct_size_mask_ge( size_t x,
+ size_t y );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+/** Constant-flow boolean "equal" comparison:
+ * return x == y
+ *
+ * This is equivalent to \p x == \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x equals to \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_size_bool_eq( size_t x,
+ size_t y );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Decide if an integer is less than the other, without branches.
+ *
+ * This is equivalent to \p x < \p y, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param x The first value to analyze.
+ * \param y The second value to analyze.
+ *
+ * \return 1 if \p x is less than \p y, otherwise 0.
+ */
+unsigned mbedtls_ct_mpi_uint_lt( const mbedtls_mpi_uint x,
+ const mbedtls_mpi_uint y );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+/** Choose between two integer values without branches.
+ *
+ * This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
+ * to code using bitwise operation rather than a branch.
+ *
+ * \param condition Condition to test.
+ * \param if1 Value to use if \p condition is nonzero.
+ * \param if0 Value to use if \p condition is zero.
+ *
+ * \return \c if1 if \p condition is nonzero, otherwise \c if0.
+ */
+unsigned mbedtls_ct_uint_if( unsigned condition,
+ unsigned if1,
+ unsigned if0 );
+
+#if defined(MBEDTLS_BIGNUM_C)
+
+/** Conditionally assign a value without branches.
+ *
+ * This is equivalent to `if ( condition ) dest = src`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param n \p dest and \p src must be arrays of limbs of size n.
+ * \param dest The MPI to conditionally assign to. This must point
+ * to an initialized MPI.
+ * \param src The MPI to be assigned from. This must point to an
+ * initialized MPI.
+ * \param condition Condition to test, must be 0 or 1.
+ */
+void mbedtls_ct_mpi_uint_cond_assign( size_t n,
+ mbedtls_mpi_uint *dest,
+ const mbedtls_mpi_uint *src,
+ unsigned char condition );
+
+#endif /* MBEDTLS_BIGNUM_C */
+
+#if defined(MBEDTLS_BASE64_C)
+
+/** Given a value in the range 0..63, return the corresponding Base64 digit.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param value A value in the range 0..63.
+ *
+ * \return A base64 digit converted from \p value.
+ */
+unsigned char mbedtls_ct_base64_enc_char( unsigned char value );
+
+/** Given a Base64 digit, return its value.
+ *
+ * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
+ * return -1.
+ *
+ * The implementation assumes that letters are consecutive (e.g. ASCII
+ * but not EBCDIC).
+ *
+ * \param c A base64 digit.
+ *
+ * \return The value of the base64 digit \p c.
+ */
+signed char mbedtls_ct_base64_dec_value( unsigned char c );
+
+#endif /* MBEDTLS_BASE64_C */
+
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
+
+/** Conditional memcpy without branches.
+ *
+ * This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
+ * to be compiled to code using bitwise operation rather than a branch.
+ *
+ * \param dest The pointer to conditionally copy to.
+ * \param src The pointer to copy from. Shouldn't overlap with \p dest.
+ * \param len The number of bytes to copy.
+ * \param c1 The first value to analyze in the condition.
+ * \param c2 The second value to analyze in the condition.
+ */
+void mbedtls_ct_memcpy_if_eq( unsigned char *dest,
+ const unsigned char *src,
+ size_t len,
+ size_t c1, size_t c2 );
+
+/** 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.
+ * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
+ *
+ * \param dest The destination buffer. This must point to a writable
+ * buffer of at least \p len bytes.
+ * \param src The base of the source buffer. This must point to a
+ * readable buffer of at least \p offset_max + \p len
+ * bytes. Shouldn't overlap with \p dest.
+ * \param offset 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.
+ * \param offset_max The maximal value of \p offset.
+ * \param len The number of bytes to copy.
+ */
+void mbedtls_ct_memcpy_offset( unsigned char *dest,
+ const unsigned char *src,
+ size_t offset,
+ size_t offset_min,
+ size_t offset_max,
+ size_t len );
+
+/** 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 first part of the message whose HMAC is being
+ * calculated. 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 buffer containing the second part of the
+ * message. 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 the second part of the
+ * message, read from \p data.
+ * \param max_data_len The maximal length of the second part of the
+ * message, read from \p data.
+ * \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 on success.
+ * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
+ * The hardware accelerator failed.
+ */
+int mbedtls_ct_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 );
+
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
+
+#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
+
+/** This function performs the unpadding part of a PKCS#1 v1.5 decryption
+ * operation (EME-PKCS1-v1_5 decoding).
+ *
+ * \note The return value from this function is a sensitive value
+ * (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
+ * in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
+ * is often a situation that an attacker can provoke and leaking which
+ * one is the result is precisely the information the attacker wants.
+ *
+ * \param mode The mode of operation. This must be either
+ * #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
+ * \param input The input buffer which is the payload inside PKCS#1v1.5
+ * encryption padding, called the "encoded message EM"
+ * by the terminology.
+ * \param ilen The length of the payload in the \p input buffer.
+ * \param output The buffer for the payload, called "message M" by the
+ * PKCS#1 terminology. This must be a writable buffer of
+ * length \p output_max_len bytes.
+ * \param olen The address at which to store the length of
+ * the payload. This must not be \c NULL.
+ * \param output_max_len The length in bytes of the output buffer \p output.
+ *
+ * \return \c 0 on success.
+ * \return #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
+ * The output buffer is too small for the unpadded payload.
+ * \return #MBEDTLS_ERR_RSA_INVALID_PADDING
+ * The input doesn't contain properly formatted padding.
+ */
+int mbedtls_ct_rsaes_pkcs1_v15_unpadding( int mode,
+ unsigned char *input,
+ size_t ilen,
+ unsigned char *output,
+ size_t output_max_len,
+ size_t *olen );
+
+#endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
diff --git a/thirdparty/mbedtls/library/constant_time_invasive.h b/thirdparty/mbedtls/library/constant_time_invasive.h
new file mode 100644
index 0000000000..4620ca1379
--- /dev/null
+++ b/thirdparty/mbedtls/library/constant_time_invasive.h
@@ -0,0 +1,51 @@
+/**
+ * \file constant_time_invasive.h
+ *
+ * \brief Constant-time module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MBEDTLS_CONSTANT_TIME_INVASIVE_H
+#define MBEDTLS_CONSTANT_TIME_INVASIVE_H
+
+#include "common.h"
+
+#if defined(MBEDTLS_TEST_HOOKS)
+
+/** Turn a value into a mask:
+ * - if \p low <= \p c <= \p high,
+ * return the all-bits 1 mask, aka (unsigned) -1
+ * - otherwise, return the all-bits 0 mask, aka 0
+ *
+ * \param low The value to analyze.
+ * \param high The value to analyze.
+ * \param c The value to analyze.
+ *
+ * \return All-bits-one if \p low <= \p c <= \p high, otherwise zero.
+ */
+unsigned char mbedtls_ct_uchar_mask_of_range( unsigned char low,
+ unsigned char high,
+ unsigned char c );
+
+#endif /* MBEDTLS_TEST_HOOKS */
+
+#endif /* MBEDTLS_CONSTANT_TIME_INVASIVE_H */
diff --git a/thirdparty/mbedtls/library/ctr_drbg.c b/thirdparty/mbedtls/library/ctr_drbg.c
index 90264e844a..a604ec0761 100644
--- a/thirdparty/mbedtls/library/ctr_drbg.c
+++ b/thirdparty/mbedtls/library/ctr_drbg.c
@@ -2,13 +2,7 @@
* CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The NIST SP 800-90 DRBGs are described in the following publication.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -81,6 +51,9 @@
void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) );
+ /* Indicate that the entropy nonce length is not set explicitly.
+ * See mbedtls_ctr_drbg_set_nonce_len(). */
+ ctx->reseed_counter = -1;
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
}
@@ -102,19 +75,49 @@ void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx )
mbedtls_aes_free( &ctx->aes_ctx );
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) );
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
+ ctx->reseed_counter = -1;
}
-void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance )
+void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx,
+ int resistance )
{
ctx->prediction_resistance = resistance;
}
-void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len )
+void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len )
{
ctx->entropy_len = len;
}
-void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval )
+int mbedtls_ctr_drbg_set_nonce_len( mbedtls_ctr_drbg_context *ctx,
+ size_t len )
+{
+ /* If mbedtls_ctr_drbg_seed() has already been called, it's
+ * too late. Return the error code that's closest to making sense. */
+ if( ctx->f_entropy != NULL )
+ return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+
+ if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+#if SIZE_MAX > INT_MAX
+ /* This shouldn't be an issue because
+ * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
+ * configuration, but make sure anyway. */
+ if( len > INT_MAX )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+#endif
+
+ /* For backward compatibility with Mbed TLS <= 2.19, store the
+ * entropy nonce length in a field that already exists, but isn't
+ * used until after the initial seeding. */
+ /* Due to the capping of len above, the value fits in an int. */
+ ctx->reseed_counter = (int) len;
+ return( 0 );
+}
+
+void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx,
+ int interval )
{
ctx->reseed_interval = interval;
}
@@ -122,7 +125,8 @@ void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int in
static int block_cipher_df( unsigned char *output,
const unsigned char *data, size_t data_len )
{
- unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
+ unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
@@ -136,7 +140,8 @@ static int block_cipher_df( unsigned char *output,
if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
- memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
+ memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
+ MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 );
mbedtls_aes_init( &aes_ctx );
/*
@@ -147,11 +152,8 @@ static int block_cipher_df( unsigned char *output,
* (Total is padded to a multiple of 16-bytes with zeroes)
*/
p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
- *p++ = ( data_len >> 24 ) & 0xff;
- *p++ = ( data_len >> 16 ) & 0xff;
- *p++ = ( data_len >> 8 ) & 0xff;
- *p++ = ( data_len ) & 0xff;
- p += 3;
+ MBEDTLS_PUT_UINT32_BE( data_len, p, 0);
+ p += 4 + 3;
*p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
memcpy( p, data, data_len );
p[data_len] = 0x80;
@@ -161,7 +163,8 @@ static int block_cipher_df( unsigned char *output,
for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ )
key[i] = i;
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -183,7 +186,8 @@ static int block_cipher_df( unsigned char *output,
use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ chain, chain ) ) != 0 )
{
goto exit;
}
@@ -200,7 +204,8 @@ static int block_cipher_df( unsigned char *output,
/*
* Do final encryption with reduced data
*/
- if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
goto exit;
}
@@ -209,7 +214,8 @@ static int block_cipher_df( unsigned char *output,
for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE )
{
- if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT,
+ iv, iv ) ) != 0 )
{
goto exit;
}
@@ -245,7 +251,7 @@ exit:
* ctx->counter = V
*/
static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
- const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
+ const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] )
{
unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
unsigned char *p = tmp;
@@ -266,8 +272,11 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/*
* Crypt counter block
*/
- if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, p ) ) != 0 )
+ {
goto exit;
+ }
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
@@ -278,9 +287,13 @@ static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx,
/*
* Update key and counter
*/
- if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ {
goto exit;
- memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE );
+ }
+ memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
+ MBEDTLS_CTR_DRBG_BLOCKSIZE );
exit:
mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
@@ -304,7 +317,7 @@ int mbedtls_ctr_drbg_update_ret( mbedtls_ctr_drbg_context *ctx,
size_t add_len )
{
unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( add_len == 0 )
return( 0 );
@@ -333,7 +346,7 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
#endif /* MBEDTLS_DEPRECATED_REMOVED */
/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
- * mbedtls_ctr_drbg_reseed(ctx, additional, len)
+ * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
* implements
* CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
* -> new_working_state
@@ -341,51 +354,57 @@ void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx,
* ctx contains working_state
* additional[:len] = additional_input
* and entropy_input comes from calling ctx->f_entropy
+ * for (ctx->entropy_len + nonce_len) bytes
* and with output
* ctx contains new_working_state
*/
-int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
- const unsigned char *additional, size_t len )
+static int mbedtls_ctr_drbg_reseed_internal( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional,
+ size_t len,
+ size_t nonce_len )
{
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ||
- len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
+ if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+ if( nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len )
+ return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
+ if( len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len )
return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );
- /*
- * Gather entropy_len bytes of entropy to seed state
- */
- if( 0 != ctx->f_entropy( ctx->p_entropy, seed,
- ctx->entropy_len ) )
+ /* Gather entropy_len bytes of entropy to seed state. */
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) )
{
return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
}
-
seedlen += ctx->entropy_len;
- /*
- * Add additional data
- */
- if( additional && len )
+ /* Gather entropy for a nonce if requested. */
+ if( nonce_len != 0 )
+ {
+ if( 0 != ctx->f_entropy( ctx->p_entropy, seed + seedlen, nonce_len ) )
+ {
+ return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED );
+ }
+ seedlen += nonce_len;
+ }
+
+ /* Add additional data if provided. */
+ if( additional != NULL && len != 0 )
{
memcpy( seed + seedlen, additional, len );
seedlen += len;
}
- /*
- * Reduce to 384 bits
- */
+ /* Reduce to 384 bits. */
if( ( ret = block_cipher_df( seed, seed, seedlen ) ) != 0 )
goto exit;
- /*
- * Update state
- */
+ /* Update state. */
if( ( ret = ctr_drbg_update_internal( ctx, seed ) ) != 0 )
goto exit;
ctx->reseed_counter = 1;
@@ -395,6 +414,25 @@ exit:
return( ret );
}
+int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
+ const unsigned char *additional, size_t len )
+{
+ return( mbedtls_ctr_drbg_reseed_internal( ctx, additional, len, 0 ) );
+}
+
+/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
+ * is sufficient to achieve the maximum security strength given the key
+ * size and entropy length. If there is enough entropy in the initial
+ * call to the entropy function to serve as both the entropy input and
+ * the nonce, don't make a second call to get a nonce. */
+static size_t good_nonce_len( size_t entropy_len )
+{
+ if( entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 )
+ return( 0 );
+ else
+ return( ( entropy_len + 1 ) / 2 );
+}
+
/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
* mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
* implements
@@ -412,8 +450,9 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
const unsigned char *custom,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
+ size_t nonce_len;
memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE );
@@ -429,33 +468,30 @@ int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx,
if( ctx->entropy_len == 0 )
ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
-
- /*
- * Initialize with an empty key
- */
- if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
+ /* ctx->reseed_counter contains the desired amount of entropy to
+ * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
+ * If it's -1, indicating that the entropy nonce length was not set
+ * explicitly, use a sufficiently large nonce for security. */
+ nonce_len = ( ctx->reseed_counter >= 0 ?
+ (size_t) ctx->reseed_counter :
+ good_nonce_len( ctx->entropy_len ) );
+
+ /* Initialize with an empty key. */
+ if( ( ret = mbedtls_aes_setkey_enc( &ctx->aes_ctx, key,
+ MBEDTLS_CTR_DRBG_KEYBITS ) ) != 0 )
{
return( ret );
}
- if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 )
+ /* Do the initial seeding. */
+ if( ( ret = mbedtls_ctr_drbg_reseed_internal( ctx, custom, len,
+ nonce_len ) ) != 0 )
{
return( ret );
}
return( 0 );
}
-/* Backward compatibility wrapper */
-int mbedtls_ctr_drbg_seed_entropy_len(
- mbedtls_ctr_drbg_context *ctx,
- int (*f_entropy)(void *, unsigned char *, size_t), void *p_entropy,
- const unsigned char *custom, size_t len,
- size_t entropy_len )
-{
- mbedtls_ctr_drbg_set_entropy_len( ctx, entropy_len );
- return( mbedtls_ctr_drbg_seed( ctx, f_entropy, p_entropy, custom, len ) );
-}
-
/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
* mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
* implements
@@ -525,11 +561,14 @@ int mbedtls_ctr_drbg_random_with_add( void *p_rng,
/*
* Crypt counter block
*/
- if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ) ) != 0 )
+ if( ( ret = mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
+ ctx->counter, tmp ) ) != 0 )
+ {
goto exit;
+ }
- use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE :
- output_len;
+ use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE )
+ ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
/*
* Copy random block to destination
*/
@@ -549,9 +588,10 @@ exit:
return( ret );
}
-int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
+int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output,
+ size_t output_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
@@ -570,7 +610,8 @@ int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_l
}
#if defined(MBEDTLS_FS_IO)
-int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
FILE *f;
@@ -579,13 +620,19 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char
if( ( f = fopen( path, "wb" ) ) == NULL )
return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR );
- if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
+ if( ( ret = mbedtls_ctr_drbg_random( ctx, buf,
+ MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 )
goto exit;
- if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT )
+ if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) !=
+ MBEDTLS_CTR_DRBG_MAX_INPUT )
+ {
ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
+ }
else
+ {
ret = 0;
+ }
exit:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -594,7 +641,8 @@ exit:
return( ret );
}
-int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path )
+int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx,
+ const char *path )
{
int ret = 0;
FILE *f = NULL;
@@ -633,45 +681,135 @@ exit:
#if defined(MBEDTLS_SELF_TEST)
-static const unsigned char entropy_source_pr[96] =
- { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16,
- 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02,
- 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b,
- 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb,
- 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9,
- 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95,
- 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63,
- 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3,
- 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31,
- 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4,
- 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56,
- 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
-
-static const unsigned char entropy_source_nopr[64] =
- { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14,
- 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe,
- 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d,
- 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20,
- 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9,
- 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46,
- 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e,
- 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
-
-static const unsigned char nonce_pers_pr[16] =
- { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2,
- 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
-
-static const unsigned char nonce_pers_nopr[16] =
- { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5,
- 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
-
-static const unsigned char result_pr[16] =
- { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f,
- 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
-
-static const unsigned char result_nopr[16] =
- { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88,
- 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+/* The CTR_DRBG NIST test vectors used here are available at
+ * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
+ *
+ * The parameters used to derive the test data are:
+ *
+ * [AES-128 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 128]
+ * [NonceLen = 64]
+ * [PersonalizationStringLen = 128]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ * [AES-256 use df]
+ * [PredictionResistance = True/False]
+ * [EntropyInputLen = 256]
+ * [NonceLen = 128]
+ * [PersonalizationStringLen = 256]
+ * [AdditionalInputLen = 0]
+ * [ReturnedBitsLen = 512]
+ *
+ */
+
+#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
+static const unsigned char entropy_source_pr[] =
+ { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
+ 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
+ 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
+ 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
+ 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
+ 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
+ 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
+
+static const unsigned char entropy_source_nopr[] =
+ { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
+ 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
+ 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
+ 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
+ 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
+
+static const unsigned char pers_pr[] =
+ { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
+ 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
+
+static const unsigned char pers_nopr[] =
+ { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
+ 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
+
+static const unsigned char result_pr[] =
+ { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
+ 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
+ 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
+ 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
+ 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
+ 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
+ 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
+ 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
+
+static const unsigned char result_nopr[] =
+ { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
+ 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
+ 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
+ 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
+ 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
+ 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
+ 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
+ 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
+#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
+
+static const unsigned char entropy_source_pr[] =
+ { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
+ 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
+ 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
+ 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
+ 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
+ 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
+ 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
+ 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
+ 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
+ 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
+ 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
+ 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
+ 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
+ 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
+
+static const unsigned char entropy_source_nopr[] =
+ { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
+ 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
+ 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
+ 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
+ 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
+ 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
+ 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
+ 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
+ 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
+ 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
+
+static const unsigned char pers_pr[] =
+ { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
+ 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
+ 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
+ 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
+
+static const unsigned char pers_nopr[] =
+ { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
+ 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
+ 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
+ 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
+
+static const unsigned char result_pr[] =
+ { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
+ 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
+ 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
+ 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
+ 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
+ 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
+ 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
+ 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
+
+static const unsigned char result_nopr[] =
+ { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
+ 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
+ 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
+ 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
+ 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
+ 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
+ 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
+ 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
+#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
static size_t test_offset;
static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
@@ -690,13 +828,15 @@ static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf,
return( 1 ); \
}
+#define SELF_TEST_OUPUT_DISCARD_LENGTH 64
+
/*
* Checkup routine
*/
int mbedtls_ctr_drbg_self_test( int verbose )
{
mbedtls_ctr_drbg_context ctx;
- unsigned char buf[16];
+ unsigned char buf[ sizeof( result_pr ) ];
mbedtls_ctr_drbg_init( &ctx );
@@ -707,15 +847,16 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_printf( " CTR_DRBG (PR = TRUE) : " );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE );
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_pr,
- nonce_pers_pr, 16 ) );
+ pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
- CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_pr ) ) );
+ CHK( memcmp( buf, result_pr, sizeof( result_pr ) ) );
mbedtls_ctr_drbg_free( &ctx );
@@ -731,15 +872,16 @@ int mbedtls_ctr_drbg_self_test( int verbose )
mbedtls_ctr_drbg_init( &ctx );
test_offset = 0;
- mbedtls_ctr_drbg_set_entropy_len( &ctx, 32 );
+ mbedtls_ctr_drbg_set_entropy_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
+ mbedtls_ctr_drbg_set_nonce_len( &ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2 );
CHK( mbedtls_ctr_drbg_seed( &ctx,
ctr_drbg_self_test_entropy,
(void *) entropy_source_nopr,
- nonce_pers_nopr, 16 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
+ pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE ) );
CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
- CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
- CHK( memcmp( buf, result_nopr, 16 ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, SELF_TEST_OUPUT_DISCARD_LENGTH ) );
+ CHK( mbedtls_ctr_drbg_random( &ctx, buf, sizeof( result_nopr ) ) );
+ CHK( memcmp( buf, result_nopr, sizeof( result_nopr ) ) );
mbedtls_ctr_drbg_free( &ctx );
diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c
index 9caa361d44..e1086008af 100644
--- a/thirdparty/mbedtls/library/debug.c
+++ b/thirdparty/mbedtls/library/debug.c
@@ -2,13 +2,7 @@
* Debugging routines
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DEBUG_C)
@@ -60,9 +29,11 @@
#define mbedtls_free free
#define mbedtls_time_t time_t
#define mbedtls_snprintf snprintf
+#define mbedtls_vsnprintf vsnprintf
#endif
#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include <stdarg.h>
#include <stdio.h>
@@ -103,13 +74,14 @@ static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
#endif
}
+MBEDTLS_PRINTF_ATTRIBUTE(5, 6)
void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line,
const char *format, ... )
{
va_list argp;
char str[DEBUG_BUF_SIZE];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( NULL == ssl ||
NULL == ssl->conf ||
@@ -120,20 +92,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
}
va_start( argp, format );
-#if defined(_WIN32)
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp );
-#else
- ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
- if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE )
- {
- str[DEBUG_BUF_SIZE-1] = '\0';
- ret = -1;
- }
-#endif
-#else
- ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
-#endif
+ ret = mbedtls_vsnprintf( str, DEBUG_BUF_SIZE, format, argp );
va_end( argp );
if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 )
@@ -168,7 +127,7 @@ void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
return;
mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
- text, ret, -ret );
+ text, ret, (unsigned int) -ret );
debug_send_line( ssl, level, file, line, str );
}
diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c
index 0867064403..91d22b5d90 100644
--- a/thirdparty/mbedtls/library/des.c
+++ b/thirdparty/mbedtls/library/des.c
@@ -2,13 +2,7 @@
* FIPS-46-3 compliant Triple-DES implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* DES, on which TDES is based, was originally designed by Horst Feistel
@@ -50,11 +23,7 @@
* http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DES_C)
@@ -76,29 +45,6 @@
#if !defined(MBEDTLS_DES_ALT)
/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-/*
* Expanded DES S-boxes
*/
static const uint32_t SB1[64] =
@@ -455,8 +401,8 @@ void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KE
int i;
uint32_t X, Y, T;
- GET_UINT32_BE( X, key, 0 );
- GET_UINT32_BE( Y, key, 4 );
+ X = MBEDTLS_GET_UINT32_BE( key, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( key, 4 );
/*
* Permuted Choice 1
@@ -665,8 +611,8 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
+ X = MBEDTLS_GET_UINT32_BE( input, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( input, 4 );
DES_IP( X, Y );
@@ -678,8 +624,8 @@ int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx,
DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
@@ -697,7 +643,7 @@ int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[8];
if( length % 8 )
@@ -759,8 +705,8 @@ int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
SK = ctx->sk;
- GET_UINT32_BE( X, input, 0 );
- GET_UINT32_BE( Y, input, 4 );
+ X = MBEDTLS_GET_UINT32_BE( input, 0 );
+ Y = MBEDTLS_GET_UINT32_BE( input, 4 );
DES_IP( X, Y );
@@ -784,8 +730,8 @@ int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx,
DES_FP( Y, X );
- PUT_UINT32_BE( Y, output, 0 );
- PUT_UINT32_BE( X, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( Y, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( X, output, 4 );
return( 0 );
}
@@ -803,7 +749,7 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx,
unsigned char *output )
{
int i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char temp[8];
if( length % 8 )
@@ -874,16 +820,16 @@ static const unsigned char des3_test_buf[8] =
static const unsigned char des3_test_ecb_dec[3][8] =
{
- { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
- { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
- { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
+ { 0x37, 0x2B, 0x98, 0xBF, 0x52, 0x65, 0xB0, 0x59 },
+ { 0xC2, 0x10, 0x19, 0x9C, 0x38, 0x5A, 0x65, 0xA1 },
+ { 0xA2, 0x70, 0x56, 0x68, 0x69, 0xE5, 0x15, 0x1D }
};
static const unsigned char des3_test_ecb_enc[3][8] =
{
- { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
- { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
- { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
+ { 0x1C, 0xD5, 0x97, 0xEA, 0x84, 0x26, 0x73, 0xFB },
+ { 0xB3, 0x92, 0x4D, 0xF3, 0xC5, 0xB5, 0x42, 0x93 },
+ { 0xDA, 0x37, 0x64, 0x41, 0xBA, 0x6F, 0x62, 0x6F }
};
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -894,16 +840,16 @@ static const unsigned char des3_test_iv[8] =
static const unsigned char des3_test_cbc_dec[3][8] =
{
- { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
- { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
- { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
+ { 0x58, 0xD9, 0x48, 0xEF, 0x85, 0x14, 0x65, 0x9A },
+ { 0x5F, 0xC8, 0x78, 0xD4, 0xD7, 0x92, 0xD9, 0x54 },
+ { 0x25, 0xF9, 0x75, 0x85, 0xA8, 0x1E, 0x48, 0xBF }
};
static const unsigned char des3_test_cbc_enc[3][8] =
{
- { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
- { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
- { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
+ { 0x91, 0x1C, 0x6D, 0xCF, 0x48, 0xA7, 0xC3, 0x4D },
+ { 0x60, 0x1A, 0x76, 0x8F, 0xA1, 0xF9, 0x66, 0xF1 },
+ { 0xA1, 0x50, 0x0F, 0x99, 0xB2, 0xCD, 0x64, 0x76 }
};
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -970,7 +916,7 @@ int mbedtls_des_self_test( int verbose )
if( ret != 0 )
goto exit;
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
if( u == 0 )
ret = mbedtls_des_crypt_ecb( &ctx, buf, buf );
@@ -1051,7 +997,7 @@ int mbedtls_des_self_test( int verbose )
if( v == MBEDTLS_DES_DECRYPT )
{
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
if( u == 0 )
ret = mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
@@ -1063,7 +1009,7 @@ int mbedtls_des_self_test( int verbose )
}
else
{
- for( j = 0; j < 10000; j++ )
+ for( j = 0; j < 100; j++ )
{
unsigned char tmp[8];
diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c
index 535b698ce6..88e148bb80 100644
--- a/thirdparty/mbedtls/library/dhm.c
+++ b/thirdparty/mbedtls/library/dhm.c
@@ -2,13 +2,7 @@
* Diffie-Hellman-Merkle key exchange
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The following sources were referenced in the design of this implementation
@@ -52,16 +25,13 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_DHM_C)
#include "mbedtls/dhm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -109,7 +79,7 @@ static int dhm_read_bignum( mbedtls_mpi *X,
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED, ret ) );
(*p) += n;
@@ -161,7 +131,7 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( p != NULL && *p != NULL );
DHM_VALIDATE_RET( end != NULL );
@@ -185,20 +155,10 @@ int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
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;
- size_t m_size = mbedtls_mpi_size( M );
- size_t m_bitlen = mbedtls_mpi_bitlen( M );
-
- count = 0;
- do
- {
- if( count++ > 30 )
- return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+ int ret;
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( R, m_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( R, ( m_size * 8 ) - m_bitlen ) );
- }
- while( dhm_check_range( R, M ) != 0 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( R, 3, M, f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( R, R, 1 ) );
cleanup:
return( ret );
@@ -271,8 +231,8 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( ( X ), \
p + 2, \
( n ) ) ); \
- *p++ = (unsigned char)( ( n ) >> 8 ); \
- *p++ = (unsigned char)( ( n ) ); \
+ *p++ = MBEDTLS_BYTE_1( n ); \
+ *p++ = MBEDTLS_BYTE_0( n ); \
p += ( n ); \
} while( 0 )
@@ -291,7 +251,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
cleanup:
if( ret != 0 && ret > -128 )
- return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED, ret );
return( ret );
}
@@ -302,7 +262,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
const mbedtls_mpi *P,
const mbedtls_mpi *G )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( P != NULL );
DHM_VALIDATE_RET( G != NULL );
@@ -310,7 +270,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
{
- return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_SET_GROUP_FAILED, ret ) );
}
ctx->len = mbedtls_mpi_size( &ctx->P );
@@ -323,7 +283,7 @@ int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
const unsigned char *input, size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( input != NULL );
@@ -331,7 +291,7 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
- return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED, ret ) );
return( 0 );
}
@@ -362,8 +322,7 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
cleanup:
if( ret != 0 && ret > -128 )
- return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
-
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED, ret );
return( ret );
}
@@ -443,7 +402,7 @@ int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi GYb;
DHM_VALIDATE_RET( ctx != NULL );
DHM_VALIDATE_RET( output != NULL );
@@ -487,7 +446,7 @@ cleanup:
mbedtls_mpi_free( &GYb );
if( ret != 0 )
- return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED, ret ) );
return( 0 );
}
@@ -521,7 +480,7 @@ void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
size_t dhminlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end;
#if defined(MBEDTLS_PEM_PARSE_C)
@@ -569,7 +528,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
@@ -578,7 +537,7 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
@@ -592,13 +551,13 @@ int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
mbedtls_mpi_free( &rec );
if ( ret != 0 )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT, ret );
goto exit;
}
if ( p != end )
{
- ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_DHM_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
goto exit;
}
}
@@ -675,7 +634,7 @@ static int load_file( const char *path, unsigned char **buf, size_t *n )
*/
int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
DHM_VALIDATE_RET( dhm != NULL );
@@ -727,7 +686,7 @@ static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_param
*/
int mbedtls_dhm_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_dhm_context dhm;
mbedtls_dhm_init( &dhm );
diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c
index 8c27e4e196..9dfa868063 100644
--- a/thirdparty/mbedtls/library/ecdh.c
+++ b/thirdparty/mbedtls/library/ecdh.c
@@ -2,13 +2,7 @@
* Elliptic curve Diffie-Hellman
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -51,16 +24,13 @@
* RFC 4492
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECDH_C)
#include "mbedtls/ecdh.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -84,6 +54,13 @@ static mbedtls_ecp_group_id mbedtls_ecdh_grp_id(
#endif
}
+int mbedtls_ecdh_can_do( mbedtls_ecp_group_id gid )
+{
+ /* At this time, all groups support ECDH. */
+ (void) gid;
+ return( 1 );
+}
+
#if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
/*
* Generate public key (restartable version)
@@ -98,7 +75,7 @@ static int ecdh_gen_public_restartable( mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* If multiplication is in progress, we already generated a privkey */
#if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -139,7 +116,7 @@ static int ecdh_compute_shared_restartable( mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point P;
mbedtls_ecp_point_init( &P );
@@ -217,7 +194,7 @@ void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx )
static int ecdh_setup_internal( mbedtls_ecdh_context_mbed *ctx,
mbedtls_ecp_group_id grp_id )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_ecp_group_load( &ctx->grp, grp_id );
if( ret != 0 )
@@ -240,6 +217,13 @@ int mbedtls_ecdh_setup( mbedtls_ecdh_context *ctx, mbedtls_ecp_group_id grp_id )
#else
switch( grp_id )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECP_DP_CURVE25519:
+ ctx->point_format = MBEDTLS_ECP_PF_COMPRESSED;
+ ctx->var = MBEDTLS_ECDH_VARIANT_EVEREST;
+ ctx->grp_id = grp_id;
+ return( mbedtls_everest_setup( &ctx->ctx.everest_ecdh, grp_id ) );
+#endif
default:
ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
ctx->var = MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0;
@@ -291,6 +275,11 @@ void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx )
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ mbedtls_everest_free( &ctx->ctx.everest_ecdh );
+ break;
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
ecdh_free_internal( &ctx->ctx.mbed_ecdh );
break;
@@ -313,7 +302,7 @@ static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t grp_len, pt_len;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
@@ -356,7 +345,7 @@ static int ecdh_make_params_internal( mbedtls_ecdh_context_mbed *ctx,
}
/*
- * Setup and write the ServerKeyExhange parameters (RFC 4492)
+ * Setup and write the ServerKeyExchange parameters (RFC 4492)
* struct {
* ECParameters curve_params;
* ECPoint public;
@@ -385,6 +374,11 @@ int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_make_params( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_make_params_internal( &ctx->ctx.mbed_ecdh, olen,
ctx->point_format, buf, blen,
@@ -415,7 +409,7 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
const unsigned char **buf,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
ECDH_VALIDATE_RET( ctx != NULL );
ECDH_VALIDATE_RET( buf != NULL );
@@ -434,6 +428,11 @@ int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_read_params( &ctx->ctx.everest_ecdh,
+ buf, end) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_read_params_internal( &ctx->ctx.mbed_ecdh,
buf, end ) );
@@ -447,7 +446,7 @@ static int ecdh_get_params_internal( mbedtls_ecdh_context_mbed *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* If it's not our key, just import the public part as Qp */
if( side == MBEDTLS_ECDH_THEIRS )
@@ -471,7 +470,7 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
const mbedtls_ecp_keypair *key,
mbedtls_ecdh_side side )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECDH_VALIDATE_RET( ctx != NULL );
ECDH_VALIDATE_RET( key != NULL );
ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS ||
@@ -498,6 +497,16 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ {
+ mbedtls_everest_ecdh_side s = side == MBEDTLS_ECDH_OURS ?
+ MBEDTLS_EVEREST_ECDH_OURS :
+ MBEDTLS_EVEREST_ECDH_THEIRS;
+ return( mbedtls_everest_get_params( &ctx->ctx.everest_ecdh,
+ key, s) );
+ }
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_get_params_internal( &ctx->ctx.mbed_ecdh,
key, side ) );
@@ -516,7 +525,7 @@ static int ecdh_make_public_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
#endif
@@ -569,6 +578,11 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_make_public( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_make_public_internal( &ctx->ctx.mbed_ecdh, olen,
ctx->point_format, buf, blen,
@@ -583,7 +597,7 @@ int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen,
static int ecdh_read_public_internal( mbedtls_ecdh_context_mbed *ctx,
const unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p,
@@ -610,6 +624,11 @@ int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_read_public( &ctx->ctx.everest_ecdh,
+ buf, blen ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_read_public_internal( &ctx->ctx.mbed_ecdh,
buf, blen ) );
@@ -628,7 +647,7 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
void *p_rng,
int restart_enabled )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_ECP_RESTARTABLE)
mbedtls_ecp_restart_ctx *rs_ctx = NULL;
#endif
@@ -662,6 +681,10 @@ static int ecdh_calc_secret_internal( mbedtls_ecdh_context_mbed *ctx,
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 );
+
+ if( mbedtls_ecp_get_type( &ctx->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ return mbedtls_mpi_write_binary_le( &ctx->z, buf, *olen );
+
return mbedtls_mpi_write_binary( &ctx->z, buf, *olen );
}
@@ -688,6 +711,11 @@ int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen,
#else
switch( ctx->var )
{
+#if defined(MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED)
+ case MBEDTLS_ECDH_VARIANT_EVEREST:
+ return( mbedtls_everest_calc_secret( &ctx->ctx.everest_ecdh, olen,
+ buf, blen, f_rng, p_rng ) );
+#endif
case MBEDTLS_ECDH_VARIANT_MBEDTLS_2_0:
return( ecdh_calc_secret_internal( &ctx->ctx.mbed_ecdh, olen, buf,
blen, f_rng, p_rng,
diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c
index 2456238b17..640eb24a26 100644
--- a/thirdparty/mbedtls/library/ecdsa.c
+++ b/thirdparty/mbedtls/library/ecdsa.c
@@ -2,13 +2,7 @@
* Elliptic curve DSA
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,11 +23,7 @@
* SEC1 http://www.secg.org/index.php?action=secg,docs_secg
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECDSA_C)
@@ -76,6 +45,7 @@
#endif
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
/* Parameter validation macros based on platform_util.h */
#define ECDSA_VALIDATE_RET( cond ) \
@@ -257,7 +227,7 @@ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx )
static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x,
const unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n_size = ( grp->nbits + 7 ) / 8;
size_t use_size = blen > n_size ? n_size : blen;
@@ -294,7 +264,7 @@ static int ecdsa_sign_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi *pk = &k, *pr = r;
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
+ if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
/* Make sure d is in range 1..n-1 */
@@ -413,6 +383,20 @@ cleanup:
return( ret );
}
+int mbedtls_ecdsa_can_do( mbedtls_ecp_group_id gid )
+{
+ switch( gid )
+ {
+#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
+ case MBEDTLS_ECP_DP_CURVE25519: return 0;
+#endif
+#ifdef MBEDTLS_ECP_DP_CURVE448_ENABLED
+ case MBEDTLS_ECP_DP_CURVE448: return 0;
+#endif
+ default: return 1;
+ }
+}
+
/*
* Compute ECDSA signature of a hashed message
*/
@@ -445,7 +429,7 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
void *p_rng_blind,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context rng_ctx;
mbedtls_hmac_drbg_context *p_rng = &rng_ctx;
unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES];
@@ -486,6 +470,8 @@ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp,
sign:
#endif
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+ (void) f_rng_blind;
+ (void) p_rng_blind;
ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen,
mbedtls_hmac_drbg_random, p_rng );
#else
@@ -509,7 +495,6 @@ sign:
mbedtls_hmac_drbg_init( &rng_ctx_blind );
p_rng_blind_det = &rng_ctx_blind;
-
mbedtls_hmac_drbg_seed_buf( p_rng_blind_det, md_info,
data, 2 * grp_len );
ret = mbedtls_hmac_drbg_update_ret( p_rng_blind_det,
@@ -567,6 +552,8 @@ cleanup:
/*
* Deterministic signature wrappers
*/
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
const unsigned char *buf, size_t blen,
@@ -581,6 +568,7 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r,
return( ecdsa_sign_det_restartable( grp, r, s, d, buf, blen, md_alg,
NULL, NULL, NULL ) );
}
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
int mbedtls_ecdsa_sign_det_ext( mbedtls_ecp_group *grp, mbedtls_mpi *r,
mbedtls_mpi *s, const mbedtls_mpi *d,
@@ -613,7 +601,7 @@ static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
const mbedtls_mpi *r, const mbedtls_mpi *s,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi e, s_inv, u1, u2;
mbedtls_ecp_point R;
mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
@@ -623,7 +611,7 @@ static int ecdsa_verify_restartable( mbedtls_ecp_group *grp,
mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 );
/* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */
- if( grp->N.p == NULL )
+ if( ! mbedtls_ecdsa_can_do( grp->id ) || grp->N.p == NULL )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
ECDSA_RS_ENTER( ver );
@@ -737,8 +725,8 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s,
unsigned char *sig, size_t *slen )
{
- int ret;
- unsigned char buf[MBEDTLS_ECDSA_MAX_LEN];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char buf[MBEDTLS_ECDSA_MAX_LEN] = {0};
unsigned char *p = buf + sizeof( buf );
size_t len = 0;
@@ -766,7 +754,7 @@ int mbedtls_ecdsa_write_signature_restartable( mbedtls_ecdsa_context *ctx,
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi r, s;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( hash != NULL );
@@ -861,7 +849,7 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
const unsigned char *sig, size_t slen,
mbedtls_ecdsa_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = (unsigned char *) sig;
const unsigned char *end = sig + slen;
size_t len;
@@ -882,8 +870,8 @@ int mbedtls_ecdsa_read_signature_restartable( mbedtls_ecdsa_context *ctx,
if( p + len != end )
{
- ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
goto cleanup;
}
@@ -943,7 +931,7 @@ int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
*/
int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECDSA_VALIDATE_RET( ctx != NULL );
ECDSA_VALIDATE_RET( key != NULL );
diff --git a/thirdparty/mbedtls/library/ecjpake.c b/thirdparty/mbedtls/library/ecjpake.c
index 0532a295e6..368b6c7124 100644
--- a/thirdparty/mbedtls/library/ecjpake.c
+++ b/thirdparty/mbedtls/library/ecjpake.c
@@ -2,13 +2,7 @@
* Elliptic curve J-PAKE
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -49,16 +22,13 @@
* available to members of the Thread Group http://threadgroup.org/
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECJPAKE_C)
#include "mbedtls/ecjpake.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -135,7 +105,7 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
const unsigned char *secret,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECJPAKE_VALIDATE_RET( ctx != NULL );
ECJPAKE_VALIDATE_RET( role == MBEDTLS_ECJPAKE_CLIENT ||
@@ -184,7 +154,7 @@ static int ecjpake_write_len_point( unsigned char **p,
const int pf,
const mbedtls_ecp_point *P )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Need at least 4 for length plus 1 for point */
@@ -196,10 +166,7 @@ static int ecjpake_write_len_point( unsigned char **p,
if( ret != 0 )
return( ret );
- (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
- (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
- (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
- (*p)[3] = (unsigned char)( ( len ) & 0xFF );
+ MBEDTLS_PUT_UINT32_BE( len, *p, 0 );
*p += 4 + len;
@@ -224,7 +191,7 @@ static int ecjpake_hash( const mbedtls_md_info_t *md_info,
const char *id,
mbedtls_mpi *h )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[ECJPAKE_HASH_BUF_LEN];
unsigned char *p = buf;
const unsigned char *end = buf + sizeof( buf );
@@ -239,10 +206,8 @@ static int ecjpake_hash( const mbedtls_md_info_t *md_info,
if( end - p < 4 )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( id_len ) & 0xFF );
+ MBEDTLS_PUT_UINT32_BE( id_len, p, 0 );
+ p += 4;
if( end < p || (size_t)( end - p ) < id_len )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
@@ -274,7 +239,7 @@ static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
const unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point V, VV;
mbedtls_mpi r, h;
size_t r_len;
@@ -303,7 +268,7 @@ static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info,
r_len = *(*p)++;
- if( end < *p || (size_t)( end - *p ) < r_len )
+ if( end < *p || (size_t)( end - *p ) < r_len || r_len == 0 )
{
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
goto cleanup;
@@ -349,7 +314,7 @@ static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point V;
mbedtls_mpi v;
mbedtls_mpi h; /* later recycled to hold r */
@@ -382,7 +347,7 @@ static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info,
goto cleanup;
}
- *(*p)++ = (unsigned char)( len & 0xFF );
+ *(*p)++ = MBEDTLS_BYTE_0( len );
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */
*p += len;
@@ -407,7 +372,7 @@ static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info,
const unsigned char **p,
const unsigned char *end )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( end < *p )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -447,7 +412,7 @@ static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( end < *p )
@@ -482,7 +447,7 @@ static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
const unsigned char *end = buf + len;
@@ -520,7 +485,7 @@ static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
const unsigned char *end = buf + len;
@@ -578,7 +543,7 @@ static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *B,
const mbedtls_ecp_point *C )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi one;
mbedtls_mpi_init( &one );
@@ -600,7 +565,7 @@ int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned char *p = buf;
const unsigned char *end = buf + len;
mbedtls_ecp_group grp;
@@ -664,7 +629,7 @@ static int ecjpake_mul_secret( mbedtls_mpi *R, int sign,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi b; /* Blinding value, then s + N * blinding */
mbedtls_mpi_init( &b );
@@ -693,7 +658,7 @@ int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point G; /* C: GA, S: GB */
mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
mbedtls_mpi xm; /* C: xc, S: xs */
@@ -775,7 +740,7 @@ int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point K;
mbedtls_mpi m_xm2_s, one;
unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
@@ -983,7 +948,7 @@ static int ecjpake_test_load( mbedtls_ecjpake_context *ctx,
const unsigned char *xm1, size_t len1,
const unsigned char *xm2, size_t len2 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) );
@@ -1033,7 +998,7 @@ static int ecjpake_lgc( void *p, unsigned char *out, size_t len )
*/
int mbedtls_ecjpake_self_test( int verbose )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecjpake_context cli;
mbedtls_ecjpake_context srv;
unsigned char buf[512], pms[32];
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index a7486c198a..7f9e1045d4 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -2,13 +2,7 @@
* Elliptic curves over GF(p): generic functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -66,11 +39,7 @@
* <http://eprint.iacr.org/2004/342.pdf>
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
/**
* \brief Function level alternative implementation.
@@ -106,8 +75,11 @@
#include "mbedtls/ecp.h"
#include "mbedtls/threading.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include "mbedtls/bn_mul.h"
+#include "ecp_invasive.h"
+
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
@@ -135,10 +107,6 @@
#include "mbedtls/hmac_drbg.h"
#elif defined(MBEDTLS_CTR_DRBG_C)
#include "mbedtls/ctr_drbg.h"
-#elif defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#elif defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
#else
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
#endif
@@ -210,6 +178,12 @@ static int ecp_drbg_seed( ecp_drbg_context *ctx,
const mbedtls_md_type_t md_type = mbedtls_md_list()[0];
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_type );
+ if( secret_len > MBEDTLS_ECP_MAX_BYTES )
+ {
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ goto cleanup;
+ }
+
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
secret_bytes, secret_len ) );
@@ -266,6 +240,12 @@ static int ecp_drbg_seed( ecp_drbg_context *ctx,
int ret;
unsigned char secret_bytes[MBEDTLS_ECP_MAX_BYTES];
+ if( secret_len > MBEDTLS_ECP_MAX_BYTES )
+ {
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ goto cleanup;
+ }
+
MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( secret,
secret_bytes, secret_len ) );
@@ -278,110 +258,9 @@ cleanup:
return( ret );
}
-#elif defined(MBEDTLS_SHA512_C) || defined(MBEDTLS_SHA256_C)
-
-/* This will be used in the self-test function */
-#define ECP_ONE_STEP_KDF
-
-/*
- * We need to expand secret data (the scalar) into a longer stream of bytes.
- *
- * We'll use the One-Step KDF from NIST SP 800-56C, with option 1 (H is a hash
- * function) and empty FixedInfo. (Though we'll make it fit the DRBG API for
- * convenience, this is not a full-fledged DRBG, but we don't need one here.)
- *
- * We need a basic hash abstraction layer to use whatever SHA-2 is available.
- */
-#if defined(MBEDTLS_SHA512_C)
-
-#define HASH_FUNC( in, ilen, out ) mbedtls_sha512_ret( in, ilen, out, 0 );
-#define HASH_BLOCK_BYTES ( 512 / 8 )
-
-#elif defined(MBEDTLS_SHA256_C)
-
-#define HASH_FUNC( in, ilen, out ) mbedtls_sha256_ret( in, ilen, out, 0 );
-#define HASH_BLOCK_BYTES ( 256 / 8 )
-
-#endif /* SHA512/SHA256 abstraction */
-
-/*
- * State consists of a 32-bit counter plus the secret value.
- *
- * We stored them concatenated in a single buffer as that's what will get
- * passed to the hash function.
- */
-typedef struct {
- size_t total_len;
- uint8_t buf[4 + MBEDTLS_ECP_MAX_BYTES];
-} ecp_drbg_context;
-
-static void ecp_drbg_init( ecp_drbg_context *ctx )
-{
- memset( ctx, 0, sizeof( ecp_drbg_context ) );
-}
-
-static void ecp_drbg_free( ecp_drbg_context *ctx )
-{
- mbedtls_platform_zeroize( ctx, sizeof( ecp_drbg_context ) );
-}
-
-static int ecp_drbg_seed( ecp_drbg_context *ctx,
- const mbedtls_mpi *secret, size_t secret_len )
-{
- ctx->total_len = 4 + secret_len;
- memset( ctx->buf, 0, 4);
- return( mbedtls_mpi_write_binary( secret, ctx->buf + 4, secret_len ) );
-}
-
-static int ecp_drbg_random( void *p_rng, unsigned char *output, size_t output_len )
-{
- ecp_drbg_context *ctx = p_rng;
- int ret;
- size_t len_done = 0;
- uint8_t tmp[HASH_BLOCK_BYTES];
-
- while( len_done < output_len )
- {
- uint8_t use_len;
-
- /* This function is only called for coordinate randomisation, which
- * happens only twice in a scalar multiplication. Each time needs a
- * random value in the range [2, p-1], and gets it by drawing len(p)
- * bytes from this function, and retrying up to 10 times if unlucky.
- *
- * So for the largest curve, each scalar multiplication draws at most
- * 20 * 66 bytes. The minimum block size is 32 (SHA-256), so with
- * rounding that means a most 20 * 3 blocks.
- *
- * Since we don't need to draw more that 255 blocks, don't bother
- * with carry propagation and just return an error instead. We can
- * change that it we even need to draw more blinding values.
- */
- ctx->buf[3] += 1;
- if( ctx->buf[3] == 0 )
- return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
-
- ret = HASH_FUNC( ctx->buf, ctx->total_len, tmp );
- if( ret != 0 )
- return( ret );
-
- if( output_len - len_done > HASH_BLOCK_BYTES )
- use_len = HASH_BLOCK_BYTES;
- else
- use_len = output_len - len_done;
-
- memcpy( output + len_done, tmp, use_len );
- len_done += use_len;
- }
-
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
-
- return( 0 );
-}
-
-#else /* DRBG/SHA modules */
+#else
#error "Invalid configuration detected. Include check_config.h to ensure that the configuration is valid."
-#endif /* DRBG/SHA modules */
+#endif /* DRBG modules */
#endif /* MBEDTLS_ECP_NO_INTERNAL_RNG */
#if defined(MBEDTLS_ECP_RESTARTABLE)
@@ -623,39 +502,10 @@ int mbedtls_ecp_check_budget( const mbedtls_ecp_group *grp,
#endif /* MBEDTLS_ECP_RESTARTABLE */
-#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
- defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
-#define ECP_SHORTWEIERSTRASS
-#endif
-
-#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) || \
- defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
-#define ECP_MONTGOMERY
-#endif
-
-/*
- * Curve types: internal for now, might be exposed later
- */
-typedef enum
-{
- ECP_TYPE_NONE = 0,
- ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
- ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
-} ecp_curve_type;
-
/*
* List of supported curves:
* - internal ID
- * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2)
+ * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2, RFC 8446 sec. 4.2.7)
* - size in bits
* - readable name
*
@@ -699,6 +549,12 @@ static const mbedtls_ecp_curve_info ecp_supported_curves[] =
#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
{ MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" },
#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+ { MBEDTLS_ECP_DP_CURVE25519, 29, 256, "x25519" },
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ { MBEDTLS_ECP_DP_CURVE448, 30, 448, "x448" },
+#endif
{ MBEDTLS_ECP_DP_NONE, 0, 0, NULL },
};
@@ -801,15 +657,15 @@ const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name
/*
* Get the type of a curve
*/
-static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
+mbedtls_ecp_curve_type mbedtls_ecp_get_type( const mbedtls_ecp_group *grp )
{
if( grp->G.X.p == NULL )
- return( ECP_TYPE_NONE );
+ return( MBEDTLS_ECP_TYPE_NONE );
if( grp->G.Y.p == NULL )
- return( ECP_TYPE_MONTGOMERY );
+ return( MBEDTLS_ECP_TYPE_MONTGOMERY );
else
- return( ECP_TYPE_SHORT_WEIERSTRASS );
+ return( MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS );
}
/*
@@ -920,7 +776,7 @@ void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key )
*/
int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( P != NULL );
ECP_VALIDATE_RET( Q != NULL );
@@ -948,7 +804,7 @@ int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src
*/
int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( pt != NULL );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) );
@@ -994,7 +850,7 @@ int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix,
const char *x, const char *y )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( P != NULL );
ECP_VALIDATE_RET( x != NULL );
ECP_VALIDATE_RET( y != NULL );
@@ -1008,14 +864,14 @@ cleanup:
}
/*
- * Export a point into unsigned binary data (SEC1 2.3.3)
+ * Export a point into unsigned binary data (SEC1 2.3.3 and RFC7748)
*/
int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P,
int format, size_t *olen,
unsigned char *buf, size_t buflen )
{
- int ret = 0;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( P != NULL );
@@ -1024,56 +880,72 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp,
ECP_VALIDATE_RET( format == MBEDTLS_ECP_PF_UNCOMPRESSED ||
format == MBEDTLS_ECP_PF_COMPRESSED );
- /*
- * Common case: P == 0
- */
- if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
- {
- if( buflen < 1 )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
-
- buf[0] = 0x00;
- *olen = 1;
-
- return( 0 );
- }
-
plen = mbedtls_mpi_size( &grp->P );
- if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ (void) format; /* Montgomery curves always use the same point format */
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
- *olen = 2 * plen + 1;
-
+ *olen = plen;
if( buflen < *olen )
return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- buf[0] = 0x04;
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &P->X, buf, plen ) );
}
- else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
- *olen = plen + 1;
+ /*
+ * Common case: P == 0
+ */
+ if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 )
+ {
+ if( buflen < 1 )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
- if( buflen < *olen )
- return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+ buf[0] = 0x00;
+ *olen = 1;
- buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ return( 0 );
+ }
+
+ if( format == MBEDTLS_ECP_PF_UNCOMPRESSED )
+ {
+ *olen = 2 * plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x04;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) );
+ }
+ else if( format == MBEDTLS_ECP_PF_COMPRESSED )
+ {
+ *olen = plen + 1;
+
+ if( buflen < *olen )
+ return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+ buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) );
+ }
}
+#endif
cleanup:
return( ret );
}
/*
- * Import a point from unsigned binary data (SEC1 2.3.4)
+ * Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748)
*/
int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *pt,
const unsigned char *buf, size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
size_t plen;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
@@ -1082,25 +954,47 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp,
if( ilen < 1 )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- if( buf[0] == 0x00 )
+ plen = mbedtls_mpi_size( &grp->P );
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
- if( ilen == 1 )
- return( mbedtls_ecp_set_zero( pt ) );
- else
+ if( plen != ilen )
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
- }
- plen = mbedtls_mpi_size( &grp->P );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &pt->X, buf, plen ) );
+ mbedtls_mpi_free( &pt->Y );
- if( buf[0] != 0x04 )
- return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+ if( grp->id == MBEDTLS_ECP_DP_CURVE25519 )
+ /* Set most significant bit to 0 as prescribed in RFC7748 §5 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &pt->X, plen * 8 - 1, 0 ) );
- if( ilen != 2 * plen + 1 )
- return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ if( buf[0] == 0x00 )
+ {
+ if( ilen == 1 )
+ return( mbedtls_ecp_set_zero( pt ) );
+ else
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+ }
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ if( buf[0] != 0x04 )
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+
+ if( ilen != 2 * plen + 1 )
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y,
+ buf + 1 + plen, plen ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) );
+ }
+#endif
cleanup:
return( ret );
@@ -1152,7 +1046,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp
int format, size_t *olen,
unsigned char *buf, size_t blen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( pt != NULL );
ECP_VALIDATE_RET( olen != NULL );
@@ -1185,7 +1079,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp
int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp,
const unsigned char **buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( buf != NULL );
@@ -1266,8 +1160,7 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
/*
* Next two bytes are the namedcurve value
*/
- buf[0] = curve_info->tls_id >> 8;
- buf[1] = curve_info->tls_id & 0xFF;
+ MBEDTLS_PUT_UINT16_BE( curve_info->tls_id, buf, 0 );
return( 0 );
}
@@ -1280,7 +1173,7 @@ int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen,
*/
static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( grp->modp == NULL )
return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) );
@@ -1332,6 +1225,18 @@ cleanup:
INC_MUL_COUNT \
} while( 0 )
+static inline int mbedtls_mpi_mul_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( X, A, B ) );
+ MOD_MUL( *X );
+cleanup:
+ return( ret );
+}
+
/*
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi
* N->s < 0 is a very fast test, which fails only if N is 0
@@ -1340,6 +1245,26 @@ cleanup:
while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) )
+#if ( defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
+ defined(MBEDTLS_ECP_ADD_MIXED_ALT) ) ) || \
+ ( defined(MBEDTLS_ECP_MONTGOMERY_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) ) )
+static inline int mbedtls_mpi_sub_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( X, A, B ) );
+ MOD_SUB( *X );
+cleanup:
+ return( ret );
+}
+#endif /* All functions referencing mbedtls_mpi_sub_mod() are alt-implemented without fallback */
+
/*
* Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int.
* We known P, N and the result are positive, so sub_abs is correct, and
@@ -1349,7 +1274,35 @@ cleanup:
while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) )
-#if defined(ECP_SHORTWEIERSTRASS)
+static inline int mbedtls_mpi_add_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ const mbedtls_mpi *A,
+ const mbedtls_mpi *B )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, A, B ) );
+ MOD_ADD( *X );
+cleanup:
+ return( ret );
+}
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) && \
+ !( defined(MBEDTLS_ECP_NO_FALLBACK) && \
+ defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && \
+ defined(MBEDTLS_ECP_ADD_MIXED_ALT) )
+static inline int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *X,
+ size_t count )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( X, count ) );
+ MOD_ADD( *X );
+cleanup:
+ return( ret );
+}
+#endif /* All functions referencing mbedtls_mpi_shift_l_mod() are alt-implemented without fallback */
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* For curves in short Weierstrass form, we do all the internal operations in
* Jacobian coordinates.
@@ -1364,9 +1317,6 @@ cleanup:
*/
static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt )
{
- int ret;
- mbedtls_mpi Zi, ZZi;
-
if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 )
return( 0 );
@@ -1375,20 +1325,25 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p
return( mbedtls_internal_ecp_normalize_jac( grp, pt ) );
#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi Zi, ZZi;
mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi );
/*
* X = X / Z^2 mod p
*/
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ZZi ) );
/*
* Y = Y / Z^3 mod p
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &Zi ) );
/*
* Z = 1
@@ -1400,6 +1355,7 @@ cleanup:
mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) */
}
/*
@@ -1416,10 +1372,6 @@ cleanup:
static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *T[], size_t T_size )
{
- int ret;
- size_t i;
- mbedtls_mpi *c, u, Zi, ZZi;
-
if( T_size < 2 )
return( ecp_normalize_jac( grp, *T ) );
@@ -1428,6 +1380,13 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
return( mbedtls_internal_ecp_normalize_jac_many( grp, T, T_size ) );
#endif
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t i;
+ mbedtls_mpi *c, u, Zi, ZZi;
+
if( ( c = mbedtls_calloc( T_size, sizeof( mbedtls_mpi ) ) ) == NULL )
return( MBEDTLS_ERR_ECP_ALLOC_FAILED );
@@ -1442,8 +1401,7 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) );
for( i = 1; i < T_size; i++ )
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) );
- MOD_MUL( c[i] );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &c[i], &c[i-1], &T[i]->Z ) );
}
/*
@@ -1462,17 +1420,17 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp,
}
else
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Zi, &u, &c[i-1] ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &u, &u, &T[i]->Z ) );
}
/*
* proceed as in normalize()
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ZZi, &Zi, &Zi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->X, &T[i]->X, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &ZZi ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T[i]->Y, &T[i]->Y, &Zi ) );
/*
* Post-precessing: reclaim some memory by shrinking coordinates
@@ -1496,6 +1454,7 @@ cleanup:
mbedtls_free( c );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) */
}
/*
@@ -1506,7 +1465,7 @@ static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp,
mbedtls_ecp_point *Q,
unsigned char inv )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char nonzero;
mbedtls_mpi mQY;
@@ -1540,9 +1499,6 @@ cleanup:
static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *P )
{
- int ret;
- mbedtls_mpi M, S, T, U;
-
#if defined(MBEDTLS_SELF_TEST)
dbl_count++;
#endif
@@ -1552,58 +1508,64 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_internal_ecp_double_jac( grp, R, P ) );
#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi M, S, T, U;
+
mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U );
/* Special case for A = -3 */
if( grp->A.p == NULL )
{
/* M = 3(X + Z^2)(X - Z^2) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &T, &P->X, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &U, &P->X, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &U ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
}
else
{
/* M = 3.X^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &P->X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M );
/* Optimize away for "koblitz" curves with A = 0 */
if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 )
{
/* M += A.Z^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &S, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &T, &grp->A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &M, &M, &S ) );
}
}
/* S = 4.X.Y^2 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &P->Y, &P->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T, 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &P->X, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &S, 1 ) );
/* U = 8.Y^4 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &T, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
/* T = M^2 - 2.S */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T, &M, &M ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T, &T, &S ) );
/* S = M(S - T) - U */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &T ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S, &S, &M ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S, &S, &U ) );
/* U = 2.Y.Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &U, &P->Y, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &U, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) );
@@ -1613,6 +1575,7 @@ cleanup:
mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) */
}
/*
@@ -1636,9 +1599,6 @@ cleanup:
static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q )
{
- int ret;
- mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
-
#if defined(MBEDTLS_SELF_TEST)
add_count++;
#endif
@@ -1648,6 +1608,12 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_internal_ecp_add_mixed( grp, R, P, Q ) );
#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_ADD_MIXED_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi T1, T2, T3, T4, X, Y, Z;
+
/*
* Trivial cases: P == 0 or Q == 0 (case 1)
*/
@@ -1666,12 +1632,12 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 );
mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &P->Z, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T1, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T1, &T1, &Q->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T2, &T2, &Q->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T1, &T1, &P->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T2, &T2, &P->Y ) );
/* Special cases (2) and (3) */
if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 )
@@ -1688,18 +1654,19 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
}
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &Z, &P->Z, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T1, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T3, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &P->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &T3 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l_mod( grp, &T1, 1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &X, &T2, &T2 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T1 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &X, &X, &T4 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &T3, &T3, &X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T3, &T3, &T2 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &T4, &T4, &P->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &Y, &T3, &T4 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) );
@@ -1711,6 +1678,7 @@ cleanup:
mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_ADD_MIXED_ALT) */
}
/*
@@ -1723,49 +1691,40 @@ cleanup:
static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
- mbedtls_mpi l, ll;
- size_t p_size;
- int count = 0;
-
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ) );
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
- p_size = ( grp->pbits + 7 ) / 8;
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi l, ll;
+
mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll );
/* Generate l such that 1 < l < p */
- do
- {
- if( count++ > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
- }
- while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
- ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
/* Z = l * Z */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Z, &pt->Z, &l ) );
/* X = l^2 * X */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &l, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->X, &pt->X, &ll ) );
/* Y = l^3 * Y */
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &ll, &ll, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &pt->Y, &pt->Y, &ll ) );
cleanup:
mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll );
+ if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) */
}
/*
@@ -1897,7 +1856,7 @@ static int ecp_precompute_comb( const mbedtls_ecp_group *grp,
unsigned char w, size_t d,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i;
size_t j = 0;
const unsigned char T_size = 1U << ( w - 1 );
@@ -2033,7 +1992,7 @@ static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_ecp_point T[], unsigned char T_size,
unsigned char i )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char ii, j;
/* Ignore the "sign" bit and scale down */
@@ -2066,7 +2025,7 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point Txi;
size_t i;
@@ -2148,7 +2107,7 @@ static int ecp_comb_recode_scalar( const mbedtls_ecp_group *grp,
unsigned char w,
unsigned char *parity_trick )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi M, mm;
mbedtls_mpi_init( &M );
@@ -2194,7 +2153,7 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char parity_trick;
unsigned char k[COMB_MAX_D + 1];
mbedtls_ecp_point *RR = R;
@@ -2276,8 +2235,10 @@ static unsigned char ecp_pick_window_size( const mbedtls_ecp_group *grp,
* Make sure w is within bounds.
* (The last test is useful only for very small curves in the test suite.)
*/
+#if( MBEDTLS_ECP_WINDOW_SIZE < 6 )
if( w > MBEDTLS_ECP_WINDOW_SIZE )
w = MBEDTLS_ECP_WINDOW_SIZE;
+#endif
if( w >= grp->nbits )
w = 2;
@@ -2303,7 +2264,7 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
void *p_rng,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char w, p_eq_g, i;
size_t d;
unsigned char T_size = 0, T_ok = 0;
@@ -2455,9 +2416,9 @@ cleanup:
return( ret );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
/*
* For Montgomery curves, we do all the internal arithmetic in projective
* coordinates. Import/export of points uses only the x coordinates, which is
@@ -2472,19 +2433,22 @@ cleanup:
*/
static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P )
{
- int ret;
-
#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_normalize_mxz( grp, P ) );
#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &P->Z ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) );
cleanup:
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) */
}
/*
@@ -2498,41 +2462,31 @@ cleanup:
static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
- mbedtls_mpi l;
- size_t p_size;
- int count = 0;
-
#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ) );
#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */
- p_size = ( grp->pbits + 7 ) / 8;
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi l;
mbedtls_mpi_init( &l );
/* Generate l such that 1 < l < p */
- do
- {
- if( count++ > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
+ MBEDTLS_MPI_CHK( mbedtls_mpi_random( &l, 2, &grp->P, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, ( p_size * 8 ) - grp->pbits ) );
- }
- while( ( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ) ||
- ( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) );
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->X, &P->X, &l ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &P->Z, &P->Z, &l ) );
cleanup:
mbedtls_mpi_free( &l );
+ if( ret == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
+ ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) */
}
/*
@@ -2555,36 +2509,39 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q,
const mbedtls_mpi *d )
{
- int ret;
- mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
-
#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
if( mbedtls_internal_ecp_grp_capable( grp ) )
return( mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ) );
#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK) && defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT)
+ return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+#else
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB;
+
mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B );
mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C );
mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &A, &P->X, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &AA, &A, &A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &B, &P->X, &P->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &BB, &B, &B ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &E, &AA, &BB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &C, &Q->X, &Q->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &D, &Q->X, &Q->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &DA, &D, &A ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &CB, &C, &B ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &S->X, &DA, &CB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->X, &S->X, &S->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mod( grp, &S->Z, &DA, &CB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, &S->Z, &S->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &S->Z, d, &S->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->X, &AA, &BB ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &grp->A, &E ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &R->Z, &BB, &R->Z ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &R->Z, &E, &R->Z ) );
cleanup:
mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B );
@@ -2592,6 +2549,7 @@ cleanup:
mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB );
return( ret );
+#endif /* !defined(MBEDTLS_ECP_NO_FALLBACK) || !defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) */
}
/*
@@ -2603,7 +2561,7 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
unsigned char b;
mbedtls_ecp_point RP;
@@ -2690,7 +2648,7 @@ cleanup:
return( ret );
}
-#endif /* ECP_MONTGOMERY */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Restartable multiplication R = m * P
@@ -2713,6 +2671,8 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
/* reset ops count for this call if top-level */
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
rs_ctx->ops_done = 0;
+#else
+ (void) rs_ctx;
#endif
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
@@ -2734,12 +2694,12 @@ int mbedtls_ecp_mul_restartable( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
}
ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
MBEDTLS_MPI_CHK( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) );
#endif
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
MBEDTLS_MPI_CHK( ecp_mul_comb( grp, R, m, P, f_rng, p_rng, rs_ctx ) );
#endif
@@ -2772,14 +2732,14 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
return( mbedtls_ecp_mul_restartable( grp, R, m, P, f_rng, p_rng, NULL ) );
}
-#if defined(ECP_SHORTWEIERSTRASS)
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
* Check that an affine point is valid as a public key,
* short weierstrass curves (SEC1 3.2.3.1)
*/
static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi YY, RHS;
/* pt coordinates must be normalized for our checks */
@@ -2795,8 +2755,8 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
* YY = Y^2
* RHS = X (X^2 + A) + B = X^3 + A X + B
*/
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY );
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &YY, &pt->Y, &pt->Y ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &pt->X, &pt->X ) );
/* Special case for A = -3 */
if( grp->A.p == NULL )
@@ -2805,11 +2765,11 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_
}
else
{
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->A ) );
}
- MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS );
- MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mod( grp, &RHS, &RHS, &pt->X ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_add_mod( grp, &RHS, &RHS, &grp->B ) );
if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 )
ret = MBEDTLS_ERR_ECP_INVALID_KEY;
@@ -2820,10 +2780,11 @@ cleanup:
return( ret );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/*
- * R = m * P with shortcuts for m == 1 and m == -1
+ * R = m * P with shortcuts for m == 0, m == 1 and m == -1
* NOT constant-time - ONLY for short Weierstrass!
*/
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
@@ -2832,9 +2793,13 @@ static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *P,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
+ if( mbedtls_mpi_cmp_int( m, 0 ) == 0 )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_ecp_set_zero( R ) );
+ }
+ else if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
}
@@ -2864,7 +2829,7 @@ int mbedtls_ecp_muladd_restartable(
const mbedtls_mpi *n, const mbedtls_ecp_point *Q,
mbedtls_ecp_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point mP;
mbedtls_ecp_point *pmP = &mP;
mbedtls_ecp_point *pR = R;
@@ -2878,7 +2843,7 @@ int mbedtls_ecp_muladd_restartable(
ECP_VALIDATE_RET( n != NULL );
ECP_VALIDATE_RET( Q != NULL );
- if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
+ if( mbedtls_ecp_get_type( grp ) != MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
mbedtls_ecp_point_init( &mP );
@@ -2967,8 +2932,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
ECP_VALIDATE_RET( Q != NULL );
return( mbedtls_ecp_muladd_restartable( grp, R, m, P, n, Q, NULL ) );
}
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_MONTGOMERY)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
#define ECP_MPI_INIT(s, n, p) {s, (n), (mbedtls_mpi_uint *)(p)}
#define ECP_MPI_INIT_ARRAY(x) \
@@ -3079,7 +3045,7 @@ static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_
return( ecp_check_bad_points_mx( &pt->X, &grp->P, grp->id ) );
}
-#endif /* ECP_MONTGOMERY */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
/*
* Check that a point is valid as a public key
@@ -3094,12 +3060,12 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 )
return( MBEDTLS_ERR_ECP_INVALID_KEY );
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
return( ecp_check_pubkey_mx( grp, pt ) );
#endif
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
return( ecp_check_pubkey_sw( grp, pt ) );
#endif
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
@@ -3114,8 +3080,8 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
{
/* see RFC 7748 sec. 5 para. 5 */
if( mbedtls_mpi_get_bit( d, 0 ) != 0 ||
@@ -3129,9 +3095,9 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
return( 0 );
}
-#endif /* ECP_MONTGOMERY */
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
{
/* see SEC1 3.2 */
if( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
@@ -3140,11 +3106,61 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp,
else
return( 0 );
}
-#endif /* ECP_SHORTWEIERSTRASS */
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+MBEDTLS_STATIC_TESTABLE
+int mbedtls_ecp_gen_privkey_mx( size_t high_bit,
+ mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+ size_t n_random_bytes = high_bit / 8 + 1;
+
+ /* [Curve25519] page 5 */
+ /* Generate a (high_bit+1)-bit random number by generating just enough
+ * random bytes, then shifting out extra bits from the top (necessary
+ * when (high_bit+1) is not a multiple of 8). */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_random_bytes,
+ f_rng, p_rng ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_random_bytes - high_bit - 1 ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, high_bit, 1 ) );
+
+ /* Make sure the last two bits are unset for Curve448, three bits for
+ Curve25519 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
+ if( high_bit == 254 )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
+ }
+
+cleanup:
+ return( ret );
+}
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+static int mbedtls_ecp_gen_privkey_sw(
+ const mbedtls_mpi *N, mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+ int ret = mbedtls_mpi_random( d, 1, N, f_rng, p_rng );
+ switch( ret )
+ {
+ case MBEDTLS_ERR_MPI_NOT_ACCEPTABLE:
+ return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
+ default:
+ return( ret );
+ }
+}
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+
/*
* Generate a private key
*/
@@ -3153,97 +3169,21 @@ int mbedtls_ecp_gen_privkey( const mbedtls_ecp_group *grp,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
- size_t n_size;
-#if defined(ECP_SHORTWEIERSTRASS)
- mbedtls_mpi one;
-
- mbedtls_mpi_init( &one );
-#endif
-
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
ECP_VALIDATE_RET( f_rng != NULL );
- n_size = ( grp->nbits + 7 ) / 8;
-
-#if defined(ECP_MONTGOMERY)
- if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
- {
- /* [M225] page 5 */
- size_t b;
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ return( mbedtls_ecp_gen_privkey_mx( grp->nbits, d, f_rng, p_rng ) );
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
- do {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
- } while( mbedtls_mpi_bitlen( d ) == 0);
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ return( mbedtls_ecp_gen_privkey_sw( &grp->N, d, f_rng, p_rng ) );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
- /* Make sure the most significant bit is nbits */
- b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
- if( b > grp->nbits )
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
- else
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
-
- /* Make sure the last two bits are unset for Curve448, three bits for
- Curve25519 */
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
- if( grp->nbits == 254 )
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
- }
- }
-#endif /* ECP_MONTGOMERY */
-
-#if defined(ECP_SHORTWEIERSTRASS)
- if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
- {
- /* SEC1 3.2.1: Generate d such that 1 <= n < N */
- int count = 0;
- unsigned lt_lower = 1, lt_upper = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &one, grp->N.n ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) );
-
- /*
- * Match the procedure given in RFC 6979 (deterministic ECDSA):
- * - use the same byte ordering;
- * - keep the leftmost nbits bits of the generated octet string;
- * - try until result is in the desired range.
- * This also avoids any biais, which is especially important for ECDSA.
- */
- do
- {
- MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
-
- /*
- * Each try has at worst a probability 1/2 of failing (the msb has
- * a probability 1/2 of being 0, and then the result will be < N),
- * so after 30 tries failure probability is a most 2**(-30).
- *
- * For most curves, 1 try is enough with overwhelming probability,
- * since N starts with a lot of 1s in binary, but some curves
- * such as secp224k1 are actually very close to the worst case.
- */
- if( ++count > 30 )
- {
- ret = MBEDTLS_ERR_ECP_RANDOM_FAILED;
- goto cleanup;
- }
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &grp->N, &lt_upper ) );
- MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( d, &one, &lt_lower ) );
- }
- while( lt_lower != 0 || lt_upper == 0 );
- }
-#endif /* ECP_SHORTWEIERSTRASS */
-
-cleanup:
-#if defined(ECP_SHORTWEIERSTRASS)
- mbedtls_mpi_free( &one );
-#endif
- return( ret );
+ return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
/*
@@ -3255,7 +3195,7 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( grp != NULL );
ECP_VALIDATE_RET( d != NULL );
ECP_VALIDATE_RET( G != NULL );
@@ -3291,7 +3231,7 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ECP_VALIDATE_RET( key != NULL );
ECP_VALIDATE_RET( f_rng != NULL );
@@ -3301,12 +3241,120 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) );
}
+#define ECP_CURVE25519_KEY_SIZE 32
+/*
+ * Read a private key.
+ */
+int mbedtls_ecp_read_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key,
+ const unsigned char *buf, size_t buflen )
+{
+ int ret = 0;
+
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+
+ if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 )
+ return( ret );
+
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ /*
+ * If it is Curve25519 curve then mask the key as mandated by RFC7748
+ */
+ if( grp_id == MBEDTLS_ECP_DP_CURVE25519 )
+ {
+ if( buflen != ECP_CURVE25519_KEY_SIZE )
+ return MBEDTLS_ERR_ECP_INVALID_KEY;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary_le( &key->d, buf, buflen ) );
+
+ /* Set the three least significant bits to 0 */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 0, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 1, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( &key->d, 2, 0 ) );
+
+ /* Set the most significant bit to 0 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 1, 0 )
+ );
+
+ /* Set the second most significant bit to 1 */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( &key->d,
+ ECP_CURVE25519_KEY_SIZE * 8 - 2, 1 )
+ );
+ }
+ else
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+ }
+
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &key->d, buf, buflen ) );
+
+ MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( &key->grp, &key->d ) );
+ }
+
+#endif
+cleanup:
+
+ if( ret != 0 )
+ mbedtls_mpi_free( &key->d );
+
+ return( ret );
+}
+
+/*
+ * Write a private key.
+ */
+int mbedtls_ecp_write_key( mbedtls_ecp_keypair *key,
+ unsigned char *buf, size_t buflen )
+{
+ int ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+ ECP_VALIDATE_RET( key != NULL );
+ ECP_VALIDATE_RET( buf != NULL );
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_MONTGOMERY )
+ {
+ if( key->grp.id == MBEDTLS_ECP_DP_CURVE25519 )
+ {
+ if( buflen < ECP_CURVE25519_KEY_SIZE )
+ return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
+
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary_le( &key->d, buf, buflen ) );
+ }
+ else
+ ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+ }
+
+#endif
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ if( mbedtls_ecp_get_type( &key->grp ) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &key->d, buf, buflen ) );
+ }
+
+#endif
+cleanup:
+
+ return( ret );
+}
+
+
/*
* Check a public-private key pair
*/
int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_point Q;
mbedtls_ecp_group grp;
ECP_VALIDATE_RET( pub != NULL );
@@ -3347,103 +3395,141 @@ cleanup:
#if defined(MBEDTLS_SELF_TEST)
-#if defined(ECP_ONE_STEP_KDF)
-/*
- * There are no test vectors from NIST for the One-Step KDF in SP 800-56C,
- * but unofficial ones can be found at:
- * https://github.com/patrickfav/singlestep-kdf/wiki/NIST-SP-800-56C-Rev1:-Non-Official-Test-Vectors
- *
- * We only use the ones with empty fixedInfo, and for brevity's sake, only
- * 40-bytes output (with SHA-256 that's more than one block, and with SHA-512
- * less than one block).
- */
-#if defined(MBEDTLS_SHA512_C)
-
-static const uint8_t test_kdf_z[16] = {
- 0x3b, 0xa9, 0x79, 0xe9, 0xbc, 0x5e, 0x3e, 0xc7,
- 0x61, 0x30, 0x36, 0xb6, 0xf5, 0x1c, 0xd5, 0xaa,
-};
-static const uint8_t test_kdf_out[40] = {
- 0x3e, 0xf6, 0xda, 0xf9, 0x51, 0x60, 0x70, 0x5f,
- 0xdf, 0x21, 0xcd, 0xab, 0xac, 0x25, 0x7b, 0x05,
- 0xfe, 0xc1, 0xab, 0x7c, 0xc9, 0x68, 0x43, 0x25,
- 0x8a, 0xfc, 0x40, 0x6e, 0x5b, 0xf7, 0x98, 0x27,
- 0x10, 0xfa, 0x7b, 0x93, 0x52, 0xd4, 0x16, 0xaa,
-};
-
-#elif defined(MBEDTLS_SHA256_C)
-
-static const uint8_t test_kdf_z[16] = {
- 0xc8, 0x3e, 0x35, 0x8e, 0x99, 0xa6, 0x89, 0xc6,
- 0x7d, 0xb4, 0xfe, 0x39, 0xcf, 0x8f, 0x26, 0xe1,
-};
-static const uint8_t test_kdf_out[40] = {
- 0x7d, 0xf6, 0x41, 0xf8, 0x3c, 0x47, 0xdc, 0x28,
- 0x5f, 0x7f, 0xaa, 0xde, 0x05, 0x64, 0xd6, 0x25,
- 0x00, 0x6a, 0x47, 0xd9, 0x1e, 0xa4, 0xa0, 0x8c,
- 0xd7, 0xf7, 0x0c, 0x99, 0xaa, 0xa0, 0x72, 0x66,
- 0x69, 0x0e, 0x25, 0xaa, 0xa1, 0x63, 0x14, 0x79,
-};
-
+/* Adjust the exponent to be a valid private point for the specified curve.
+ * This is sometimes necessary because we use a single set of exponents
+ * for all curves but the validity of values depends on the curve. */
+static int self_test_adjust_exponent( const mbedtls_ecp_group *grp,
+ mbedtls_mpi *m )
+{
+ int ret = 0;
+ switch( grp->id )
+ {
+ /* If Curve25519 is available, then that's what we use for the
+ * Montgomery test, so we don't need the adjustment code. */
+#if ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ case MBEDTLS_ECP_DP_CURVE448:
+ /* Move highest bit from 254 to N-1. Setting bit N-1 is
+ * necessary to enforce the highest-bit-set constraint. */
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, 254, 0 ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( m, grp->nbits, 1 ) );
+ /* Copy second-highest bit from 253 to N-2. This is not
+ * necessary but improves the test variety a bit. */
+ MBEDTLS_MPI_CHK(
+ mbedtls_mpi_set_bit( m, grp->nbits - 1,
+ mbedtls_mpi_get_bit( m, 253 ) ) );
+ break;
#endif
+#endif /* ! defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) */
+ default:
+ /* Non-Montgomery curves and Curve25519 need no adjustment. */
+ (void) grp;
+ (void) m;
+ goto cleanup;
+ }
+cleanup:
+ return( ret );
+}
-static int ecp_kdf_self_test( void )
+/* Calculate R = m.P for each m in exponents. Check that the number of
+ * basic operations doesn't depend on the value of m. */
+static int self_test_point( int verbose,
+ mbedtls_ecp_group *grp,
+ mbedtls_ecp_point *R,
+ mbedtls_mpi *m,
+ const mbedtls_ecp_point *P,
+ const char *const *exponents,
+ size_t n_exponents )
{
- int ret;
- ecp_drbg_context kdf_ctx;
- mbedtls_mpi scalar;
- uint8_t out[sizeof( test_kdf_out )];
-
- ecp_drbg_init( &kdf_ctx );
- mbedtls_mpi_init( &scalar );
- memset( out, 0, sizeof( out ) );
+ int ret = 0;
+ size_t i = 0;
+ unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
+ add_count = 0;
+ dbl_count = 0;
+ mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &scalar,
- test_kdf_z, sizeof( test_kdf_z ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[0] ) );
+ MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
- MBEDTLS_MPI_CHK( ecp_drbg_seed( &kdf_ctx,
- &scalar, sizeof( test_kdf_z ) ) );
+ for( i = 1; i < n_exponents; i++ )
+ {
+ add_c_prev = add_count;
+ dbl_c_prev = dbl_count;
+ mul_c_prev = mul_count;
+ add_count = 0;
+ dbl_count = 0;
+ mul_count = 0;
- MBEDTLS_MPI_CHK( ecp_drbg_random( &kdf_ctx, out, sizeof( out ) ) );
+ MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( m, 16, exponents[i] ) );
+ MBEDTLS_MPI_CHK( self_test_adjust_exponent( grp, m ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
- if( memcmp( out, test_kdf_out, sizeof( out ) ) != 0 )
- ret = -1;
+ if( add_count != add_c_prev ||
+ dbl_count != dbl_c_prev ||
+ mul_count != mul_c_prev )
+ {
+ ret = 1;
+ break;
+ }
+ }
cleanup:
- ecp_drbg_free( &kdf_ctx );
- mbedtls_mpi_free( &scalar );
-
+ if( verbose != 0 )
+ {
+ if( ret != 0 )
+ mbedtls_printf( "failed (%u)\n", (unsigned int) i );
+ else
+ mbedtls_printf( "passed\n" );
+ }
return( ret );
}
-#endif /* ECP_ONE_STEP_KDF */
/*
* Checkup routine
*/
int mbedtls_ecp_self_test( int verbose )
{
- int ret;
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group grp;
mbedtls_ecp_point R, P;
mbedtls_mpi m;
- unsigned long add_c_prev, dbl_c_prev, mul_c_prev;
- /* exponents especially adapted for secp192r1 */
- const char *exponents[] =
+
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
+ /* Exponents especially adapted for secp192k1, which has the lowest
+ * order n of all supported curves (secp192r1 is in a slightly larger
+ * field but the order of its base point is slightly smaller). */
+ const char *sw_exponents[] =
{
"000000000000000000000000000000000000000000000001", /* one */
- "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */
+ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8C", /* n - 1 */
"5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */
"400000000000000000000000000000000000000000000000", /* one and zeros */
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */
"555555555555555555555555555555555555555555555555", /* 101010... */
};
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+ const char *m_exponents[] =
+ {
+ /* Valid private values for Curve25519. In a build with Curve448
+ * but not Curve25519, they will be adjusted in
+ * self_test_adjust_exponent(). */
+ "4000000000000000000000000000000000000000000000000000000000000000",
+ "5C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C30",
+ "5715ECCE24583F7A7023C24164390586842E816D7280A49EF6DF4EAE6B280BF8",
+ "41A2B017516F6D254E1F002BCCBADD54BE30F8CEC737A0E912B4963B6BA74460",
+ "5555555555555555555555555555555555555555555555555555555555555550",
+ "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8",
+ };
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
mbedtls_ecp_group_init( &grp );
mbedtls_ecp_point_init( &R );
mbedtls_ecp_point_init( &P );
mbedtls_mpi_init( &m );
+#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/* Use secp192r1 if available, or any available curve */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) );
@@ -3452,104 +3538,53 @@ int mbedtls_ecp_self_test( int verbose )
#endif
if( verbose != 0 )
- mbedtls_printf( " ECP test #1 (constant op_count, base point G): " );
-
+ mbedtls_printf( " ECP SW test #1 (constant op_count, base point G): " );
/* Do a dummy multiplication first to trigger precomputation */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) );
-
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
-
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) );
-
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
-
- ret = 1;
- goto cleanup;
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &grp.G,
+ sw_exponents,
+ sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
+ if( ret != 0 )
+ goto cleanup;
if( verbose != 0 )
- mbedtls_printf( " ECP test #2 (constant op_count, other point): " );
+ mbedtls_printf( " ECP SW test #2 (constant op_count, other point): " );
/* We computed P = 2G last time, use it */
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &P,
+ sw_exponents,
+ sizeof( sw_exponents ) / sizeof( sw_exponents[0] ));
+ if( ret != 0 )
+ goto cleanup;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
-
- for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ )
- {
- add_c_prev = add_count;
- dbl_c_prev = dbl_count;
- mul_c_prev = mul_count;
- add_count = 0;
- dbl_count = 0;
- mul_count = 0;
-
- MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) );
-
- if( add_count != add_c_prev ||
- dbl_count != dbl_c_prev ||
- mul_count != mul_c_prev )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed (%u)\n", (unsigned int) i );
-
- ret = 1;
- goto cleanup;
- }
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
+ mbedtls_ecp_group_free( &grp );
+ mbedtls_ecp_point_free( &R );
+#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
-#if defined(ECP_ONE_STEP_KDF)
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
if( verbose != 0 )
- mbedtls_printf( " ECP test #3 (internal KDF): " );
-
- ret = ecp_kdf_self_test();
+ mbedtls_printf( " ECP Montgomery test (constant op_count): " );
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+ MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE25519 ) );
+#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
+ MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_CURVE448 ) );
+#else
+#error "MBEDTLS_ECP_MONTGOMERY_ENABLED is defined, but no curve is supported for self-test"
+#endif
+ ret = self_test_point( verbose,
+ &grp, &R, &m, &grp.G,
+ m_exponents,
+ sizeof( m_exponents ) / sizeof( m_exponents[0] ));
if( ret != 0 )
- {
- if( verbose != 0 )
- mbedtls_printf( "failed\n" );
-
- ret = 1;
goto cleanup;
- }
-
- if( verbose != 0 )
- mbedtls_printf( "passed\n" );
-#endif /* ECP_ONE_STEP_KDF */
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
cleanup:
if( ret < 0 && verbose != 0 )
- mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
+ mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
mbedtls_ecp_group_free( &grp );
mbedtls_ecp_point_free( &R );
diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c
index afa3b6324e..ff26a18e8f 100644
--- a/thirdparty/mbedtls/library/ecp_curves.c
+++ b/thirdparty/mbedtls/library/ecp_curves.c
@@ -2,13 +2,7 @@
* Elliptic curves over GF(p): curve-specific data and functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,41 +15,19 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ECP_C)
#include "mbedtls/ecp.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include "mbedtls/bn_mul.h"
+#include "ecp_invasive.h"
+
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
@@ -548,6 +520,22 @@ static const mbedtls_mpi_uint brainpoolP512r1_n[] = {
};
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+/* For these curves, we build the group parameters dynamically. */
+#define ECP_LOAD_GROUP
+#endif
+
+#if defined(ECP_LOAD_GROUP)
/*
* Create an MPI from embedded constants
* (assumes len is an exact multiple of sizeof mbedtls_mpi_uint)
@@ -598,6 +586,7 @@ static int ecp_group_load( mbedtls_ecp_group *grp,
return( 0 );
}
+#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_NIST_OPTIM)
/* Forward declarations */
@@ -639,6 +628,7 @@ static int ecp_mod_p224k1( mbedtls_mpi * );
static int ecp_mod_p256k1( mbedtls_mpi * );
#endif
+#if defined(ECP_LOAD_GROUP)
#define LOAD_GROUP_A( G ) ecp_group_load( grp, \
G ## _p, sizeof( G ## _p ), \
G ## _a, sizeof( G ## _a ), \
@@ -654,6 +644,7 @@ static int ecp_mod_p256k1( mbedtls_mpi * );
G ## _gx, sizeof( G ## _gx ), \
G ## _gy, sizeof( G ## _gy ), \
G ## _n, sizeof( G ## _n ) )
+#endif /* ECP_LOAD_GROUP */
#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
/* Constants used by ecp_use_curve25519() */
@@ -668,7 +659,7 @@ static const unsigned char curve25519_part_of_n[] = {
*/
static int ecp_use_curve25519( mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Actually ( A + 2 ) / 4 */
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->A, curve25519_a24 ) );
@@ -717,7 +708,7 @@ static const unsigned char curve448_part_of_n[] = {
static int ecp_use_curve448( mbedtls_ecp_group *grp )
{
mbedtls_mpi Ns;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_init( &Ns );
@@ -844,7 +835,7 @@ int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id )
#endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
default:
- mbedtls_ecp_group_free( grp );
+ grp->id = MBEDTLS_ECP_DP_NONE;
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
}
}
@@ -908,7 +899,7 @@ static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry )
*/
static int ecp_mod_p192( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi_uint c = 0;
mbedtls_mpi_uint *p, *end;
@@ -994,25 +985,20 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
#define ADD( j ) add32( &cur, A( j ), &c );
#define SUB( j ) sub32( &cur, A( j ), &c );
+#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
+#define biL (ciL << 3) /* bits in limb */
+
/*
* Helpers for the main 'loop'
- * (see fix_negative for the motivation of C)
*/
#define INIT( b ) \
- int ret; \
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; \
signed char c = 0, cc; \
uint32_t cur; \
size_t i = 0, bits = (b); \
- mbedtls_mpi C; \
- mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \
- \
- C.s = 1; \
- C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \
- C.p = Cp; \
- memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \
- \
- MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \
- sizeof( mbedtls_mpi_uint ) ) ); \
+ /* N is the size of the product of two b-bit numbers, plus one */ \
+ /* limb for fix_negative */ \
+ MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, ( b ) * 2 / biL + 1 ) ); \
LOAD32;
#define NEXT \
@@ -1027,33 +1013,41 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry )
STORE32; i++; \
cur = c > 0 ? c : 0; STORE32; \
cur = 0; while( ++i < MAX32 ) { STORE32; } \
- if( c < 0 ) MBEDTLS_MPI_CHK( fix_negative( N, c, &C, bits ) );
+ if( c < 0 ) mbedtls_ecp_fix_negative( N, c, bits );
/*
* If the result is negative, we get it in the form
* c * 2^bits + N, with c negative and N positive shorter than 'bits'
*/
-static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits )
+MBEDTLS_STATIC_TESTABLE
+void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits )
{
- int ret;
-
- /* C = - c * 2^bits */
-#if !defined(MBEDTLS_HAVE_INT64)
- ((void) bits);
-#else
- if( bits == 224 )
- C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32;
- else
-#endif
- C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c;
+ size_t i;
- /* N = - ( C - N ) */
- MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) );
+ /* Set N := 2^bits - 1 - N. We know that 0 <= N < 2^bits, so
+ * set the absolute value to 0xfff...fff - N. There is no carry
+ * since we're subtracting from all-bits-one. */
+ for( i = 0; i <= bits / 8 / sizeof( mbedtls_mpi_uint ); i++ )
+ {
+ N->p[i] = ~(mbedtls_mpi_uint)0 - N->p[i];
+ }
+ /* Add 1, taking care of the carry. */
+ i = 0;
+ do
+ ++N->p[i];
+ while( N->p[i++] == 0 && i <= bits / 8 / sizeof( mbedtls_mpi_uint ) );
+ /* Invert the sign.
+ * Now N = N0 - 2^bits where N0 is the initial value of N. */
N->s = -1;
-cleanup:
-
- return( ret );
+ /* Add |c| * 2^bits to the absolute value. Since c and N are
+ * negative, this adds c * 2^bits. */
+ mbedtls_mpi_uint msw = (mbedtls_mpi_uint) -c;
+#if defined(MBEDTLS_HAVE_INT64)
+ if( bits == 224 )
+ msw <<= 32;
+#endif
+ N->p[bits / 8 / sizeof( mbedtls_mpi_uint)] += msw;
}
#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
@@ -1193,7 +1187,7 @@ cleanup:
*/
static int ecp_mod_p521( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M;
mbedtls_mpi_uint Mp[P521_WIDTH + 1];
@@ -1242,7 +1236,7 @@ cleanup:
*/
static int ecp_mod_p255( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M;
mbedtls_mpi_uint Mp[P255_WIDTH + 2];
@@ -1299,7 +1293,7 @@ cleanup:
*/
static int ecp_mod_p448( mbedtls_mpi *N )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M, Q;
mbedtls_mpi_uint Mp[P448_WIDTH + 1], Qp[P448_WIDTH];
@@ -1361,7 +1355,7 @@ cleanup:
static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs,
size_t adjust, size_t shift, mbedtls_mpi_uint mask )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_mpi M, R;
mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1];
diff --git a/thirdparty/mbedtls/library/ecp_invasive.h b/thirdparty/mbedtls/library/ecp_invasive.h
new file mode 100644
index 0000000000..71c7702758
--- /dev/null
+++ b/thirdparty/mbedtls/library/ecp_invasive.h
@@ -0,0 +1,81 @@
+/**
+ * \file ecp_invasive.h
+ *
+ * \brief ECP module: interfaces for invasive testing only.
+ *
+ * The interfaces in this file are intended for testing purposes only.
+ * They SHOULD NOT be made available in library integrations except when
+ * building the library for testing.
+ */
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MBEDTLS_ECP_INVASIVE_H
+#define MBEDTLS_ECP_INVASIVE_H
+
+#include "common.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/ecp.h"
+
+#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_C)
+
+#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
+ defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
+/* Preconditions:
+ * - bits is a multiple of 64 or is 224
+ * - c is -1 or -2
+ * - 0 <= N < 2^bits
+ * - N has room for bits plus one limb
+ *
+ * Behavior:
+ * Set N to c * 2^bits + old_value_of_N.
+ */
+void mbedtls_ecp_fix_negative( mbedtls_mpi *N, signed char c, size_t bits );
+#endif
+
+#if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
+/** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
+ *
+ * This function implements key generation for the set of secret keys
+ * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value
+ * has the lower bits masked but is not necessarily canonical.
+ *
+ * \note - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+ * - [RFC7748] https://tools.ietf.org/html/rfc7748
+ *
+ * \p high_bit The position of the high-order bit of the key to generate.
+ * This is the bit-size of the key minus 1:
+ * 254 for Curve25519 or 447 for Curve448.
+ * \param d The randomly generated key. This is a number of size
+ * exactly \p n_bits + 1 bits, with the least significant bits
+ * masked as specified in [Curve25519] and in [RFC7748] §5.
+ * \param f_rng The RNG function.
+ * \param p_rng The RNG context to be passed to \p f_rng.
+ *
+ * \return \c 0 on success.
+ * \return \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
+ */
+int mbedtls_ecp_gen_privkey_mx( size_t n_bits,
+ mbedtls_mpi *d,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng );
+
+#endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
+
+#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
+
+#endif /* MBEDTLS_ECP_INVASIVE_H */
diff --git a/thirdparty/mbedtls/library/entropy.c b/thirdparty/mbedtls/library/entropy.c
index 9f1a32bdc1..12fd3b9b5f 100644
--- a/thirdparty/mbedtls/library/entropy.c
+++ b/thirdparty/mbedtls/library/entropy.c
@@ -2,13 +2,7 @@
* Entropy accumulator implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_ENTROPY_C)
@@ -61,6 +30,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -266,7 +236,7 @@ cleanup:
int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@@ -288,7 +258,9 @@ int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
*/
static int entropy_gather_internal( mbedtls_entropy_context *ctx )
{
- int ret, i, have_one_strong = 0;
+ int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+ int i;
+ int have_one_strong = 0;
unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
size_t olen;
@@ -336,7 +308,7 @@ cleanup:
*/
int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
@@ -355,7 +327,8 @@ int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
{
- int ret, count = 0, i, done;
+ int ret, count = 0, i, thresholds_reached;
+ size_t strong_size;
mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
@@ -393,12 +366,17 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
- done = 1;
+ thresholds_reached = 1;
+ strong_size = 0;
for( i = 0; i < ctx->source_count; i++ )
+ {
if( ctx->source[i].size < ctx->source[i].threshold )
- done = 0;
+ thresholds_reached = 0;
+ if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
+ strong_size += ctx->source[i].size;
+ }
}
- while( ! done );
+ while( ! thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE );
memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
@@ -493,7 +471,7 @@ int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
#if defined(MBEDTLS_FS_IO)
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
{
- int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f = NULL;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c
index 2095a7dd34..40f23fd2a6 100644
--- a/thirdparty/mbedtls/library/entropy_poll.c
+++ b/thirdparty/mbedtls/library/entropy_poll.c
@@ -2,13 +2,7 @@
* Platform-specific and custom entropy polling functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#if defined(__linux__) && !defined(_GNU_SOURCE)
@@ -49,11 +22,7 @@
#define _GNU_SOURCE
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include <string.h>
@@ -61,6 +30,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/entropy_poll.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_TIMING_C)
#include "mbedtls/timing.h"
@@ -76,7 +46,7 @@
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
#endif
@@ -134,7 +104,7 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len
* Since there is no wrapper in the libc yet, use the generic syscall wrapper
* available in GNU libc and compatible libc's (eg uClibc).
*/
-#if defined(__linux__) && defined(__GLIBC__)
+#if ((defined(__linux__) && defined(__GLIBC__)) || defined(__midipix__))
#include <unistd.h>
#include <sys/syscall.h>
#if defined(SYS_getrandom)
@@ -152,7 +122,57 @@ static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
return( syscall( SYS_getrandom, buf, buflen, flags ) );
}
#endif /* SYS_getrandom */
-#endif /* __linux__ */
+#endif /* __linux__ || __midipix__ */
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#if (defined(__FreeBSD__) && __FreeBSD_version >= 1200000) || \
+ (defined(__DragonFly__) && __DragonFly_version >= 500700)
+#include <errno.h>
+#include <sys/random.h>
+#define HAVE_GETRANDOM
+static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
+{
+ return getrandom( buf, buflen, flags );
+}
+#endif /* (__FreeBSD__ && __FreeBSD_version >= 1200000) ||
+ (__DragonFly__ && __DragonFly_version >= 500700) */
+#endif /* __FreeBSD__ || __DragonFly__ */
+
+/*
+ * Some BSD systems provide KERN_ARND.
+ * This is equivalent to reading from /dev/urandom, only it doesn't require an
+ * open file descriptor, and provides up to 256 bytes per call (basically the
+ * same as getentropy(), but with a longer history).
+ *
+ * Documentation: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7
+ */
+#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(HAVE_GETRANDOM)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#if defined(KERN_ARND)
+#define HAVE_SYSCTL_ARND
+
+static int sysctl_arnd_wrapper( unsigned char *buf, size_t buflen )
+{
+ int name[2];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_ARND;
+
+ while( buflen > 0 )
+ {
+ len = buflen > 256 ? 256 : buflen;
+ if( sysctl(name, 2, buf, &len, NULL, 0) == -1 )
+ return( -1 );
+ buflen -= len;
+ buf += len;
+ }
+ return( 0 );
+}
+#endif /* KERN_ARND */
+#endif /* __FreeBSD__ || __NetBSD__ */
#include <stdio.h>
@@ -161,7 +181,7 @@ int mbedtls_platform_entropy_poll( void *data,
{
FILE *file;
size_t read_len;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) data);
#if defined(HAVE_GETRANDOM)
@@ -178,6 +198,15 @@ int mbedtls_platform_entropy_poll( void *data,
((void) ret);
#endif /* HAVE_GETRANDOM */
+#if defined(HAVE_SYSCTL_ARND)
+ ((void) file);
+ ((void) read_len);
+ if( sysctl_arnd_wrapper( output, len ) == -1 )
+ return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
+ *olen = len;
+ return( 0 );
+#else
+
*olen = 0;
file = fopen( "/dev/urandom", "rb" );
@@ -195,6 +224,7 @@ int mbedtls_platform_entropy_poll( void *data,
*olen = len;
return( 0 );
+#endif /* HAVE_SYSCTL_ARND */
}
#endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
@@ -205,13 +235,13 @@ int mbedtls_null_entropy_poll( void *data,
{
((void) data);
((void) output);
- *olen = 0;
+ *olen = 0;
if( len < sizeof(unsigned char) )
return( 0 );
+ output[0] = 0;
*olen = sizeof(unsigned char);
-
return( 0 );
}
#endif
diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c
index b83b8d1f1b..afad38904f 100644
--- a/thirdparty/mbedtls/library/error.c
+++ b/thirdparty/mbedtls/library/error.c
@@ -2,13 +2,7 @@
* Error message information
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+#include "common.h"
#include "mbedtls/error.h"
+#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY)
+
#if defined(MBEDTLS_ERROR_C)
#if defined(MBEDTLS_PLATFORM_C)
@@ -137,6 +106,10 @@
#include "mbedtls/entropy.h"
#endif
+#if defined(MBEDTLS_ERROR_C)
+#include "mbedtls/error.h"
+#endif
+
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#endif
@@ -238,692 +211,751 @@
#endif
-void mbedtls_strerror( int ret, char *buf, size_t buflen )
+const char * mbedtls_high_level_strerr( int error_code )
{
- size_t len;
- int use_ret;
+ int high_level_error_code;
- if( buflen == 0 )
- return;
-
- memset( buf, 0x00, buflen );
+ if( error_code < 0 )
+ error_code = -error_code;
- if( ret < 0 )
- ret = -ret;
+ /* Extract the high-level part from the error code. */
+ high_level_error_code = error_code & 0xFF80;
- if( ret & 0xFF80 )
+ switch( high_level_error_code )
{
- use_ret = ret & 0xFF80;
-
- // High level error codes
- //
- // BEGIN generated code
+ /* Begin Auto-Generated Code. */
#if defined(MBEDTLS_CIPHER_C)
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) )
- mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid. For example, because it was freed" );
- if( use_ret == -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CIPHER - Cipher hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE):
+ return( "CIPHER - The selected feature is not available" );
+ case -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA):
+ return( "CIPHER - Bad input parameters" );
+ case -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED):
+ return( "CIPHER - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_CIPHER_INVALID_PADDING):
+ return( "CIPHER - Input data contains invalid padding and is rejected" );
+ case -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED):
+ return( "CIPHER - Decryption of block requires a full block" );
+ case -(MBEDTLS_ERR_CIPHER_AUTH_FAILED):
+ return( "CIPHER - Authentication failed (for AEAD modes)" );
+ case -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT):
+ return( "CIPHER - The context is invalid. For example, because it was freed" );
+ case -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED):
+ return( "CIPHER - Cipher hardware accelerator failed" );
#endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C)
- if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
- if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "DHM - Read or write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - DHM hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED) )
- mbedtls_snprintf( buf, buflen, "DHM - Setting the modulus and generator failed" );
+ case -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA):
+ return( "DHM - Bad input parameters" );
+ case -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED):
+ return( "DHM - Reading of the DHM parameters failed" );
+ case -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED):
+ return( "DHM - Making of the DHM parameters failed" );
+ case -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED):
+ return( "DHM - Reading of the public values failed" );
+ case -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED):
+ return( "DHM - Making of the public value failed" );
+ case -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED):
+ return( "DHM - Calculation of the DHM secret failed" );
+ case -(MBEDTLS_ERR_DHM_INVALID_FORMAT):
+ return( "DHM - The ASN.1 data is not formatted correctly" );
+ case -(MBEDTLS_ERR_DHM_ALLOC_FAILED):
+ return( "DHM - Allocation of memory failed" );
+ case -(MBEDTLS_ERR_DHM_FILE_IO_ERROR):
+ return( "DHM - Read or write of file failed" );
+ case -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED):
+ return( "DHM - DHM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED):
+ return( "DHM - Setting the modulus and generator failed" );
#endif /* MBEDTLS_DHM_C */
#if defined(MBEDTLS_ECP_C)
- if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "ECP - The requested feature is not available, for example, the requested curve is not supported" );
- if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
- if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as ephemeral key, failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
- mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
- if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ECP - The buffer contains a valid signature followed by more data" );
- if( use_ret == -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ECP - The ECP hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_ECP_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "ECP - Operation in progress, call again with the same parameters to continue" );
+ case -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA):
+ return( "ECP - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL):
+ return( "ECP - The buffer is too small to write to" );
+ case -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE):
+ return( "ECP - The requested feature is not available, for example, the requested curve is not supported" );
+ case -(MBEDTLS_ERR_ECP_VERIFY_FAILED):
+ return( "ECP - The signature is not valid" );
+ case -(MBEDTLS_ERR_ECP_ALLOC_FAILED):
+ return( "ECP - Memory allocation failed" );
+ case -(MBEDTLS_ERR_ECP_RANDOM_FAILED):
+ return( "ECP - Generation of random value, such as ephemeral key, failed" );
+ case -(MBEDTLS_ERR_ECP_INVALID_KEY):
+ return( "ECP - Invalid private or public key" );
+ case -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH):
+ return( "ECP - The buffer contains a valid signature followed by more data" );
+ case -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED):
+ return( "ECP - The ECP hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ECP_IN_PROGRESS):
+ return( "ECP - Operation in progress, call again with the same parameters to continue" );
#endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_MD_C)
- if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
- if( use_ret == -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD - MD hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE):
+ return( "MD - The selected feature is not available" );
+ case -(MBEDTLS_ERR_MD_BAD_INPUT_DATA):
+ return( "MD - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_MD_ALLOC_FAILED):
+ return( "MD - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_MD_FILE_IO_ERROR):
+ return( "MD - Opening or reading of file failed" );
+ case -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED):
+ return( "MD - MD hardware accelerator failed" );
#endif /* MBEDTLS_MD_C */
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
- if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
- mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
- if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
- mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
- if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
- mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT):
+ return( "PEM - No PEM header or footer found" );
+ case -(MBEDTLS_ERR_PEM_INVALID_DATA):
+ return( "PEM - PEM string is not as expected" );
+ case -(MBEDTLS_ERR_PEM_ALLOC_FAILED):
+ return( "PEM - Failed to allocate memory" );
+ case -(MBEDTLS_ERR_PEM_INVALID_ENC_IV):
+ return( "PEM - RSA IV is not in hex-format" );
+ case -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG):
+ return( "PEM - Unsupported key encryption algorithm" );
+ case -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED):
+ return( "PEM - Private key password can't be empty" );
+ case -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH):
+ return( "PEM - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE):
+ return( "PEM - Unavailable feature, e.g. hashing/encryption combination" );
+ case -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA):
+ return( "PEM - Bad input parameters to function" );
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */
#if defined(MBEDTLS_PK_C)
- if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
- if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
- if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
- mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
- mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
- if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
- if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PK - The buffer contains a valid signature followed by more data" );
- if( use_ret == -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "PK - PK hardware accelerator failed" );
+ case -(MBEDTLS_ERR_PK_ALLOC_FAILED):
+ return( "PK - Memory allocation failed" );
+ case -(MBEDTLS_ERR_PK_TYPE_MISMATCH):
+ return( "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
+ case -(MBEDTLS_ERR_PK_BAD_INPUT_DATA):
+ return( "PK - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PK_FILE_IO_ERROR):
+ return( "PK - Read/write of file failed" );
+ case -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION):
+ return( "PK - Unsupported key version" );
+ case -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT):
+ return( "PK - Invalid key tag or value" );
+ case -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG):
+ return( "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
+ case -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED):
+ return( "PK - Private key password can't be empty" );
+ case -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH):
+ return( "PK - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PK_INVALID_PUBKEY):
+ return( "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
+ case -(MBEDTLS_ERR_PK_INVALID_ALG):
+ return( "PK - The algorithm tag or value is invalid" );
+ case -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE):
+ return( "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
+ case -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE):
+ return( "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
+ case -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH):
+ return( "PK - The buffer contains a valid signature followed by more data" );
+ case -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED):
+ return( "PK - PK hardware accelerator failed" );
#endif /* MBEDTLS_PK_C */
#if defined(MBEDTLS_PKCS12_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
- if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA):
+ return( "PKCS12 - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE):
+ return( "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
+ case -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT):
+ return( "PKCS12 - PBE ASN.1 data not as expected" );
+ case -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH):
+ return( "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS12_C */
#if defined(MBEDTLS_PKCS5_C)
- if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
- if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
+ case -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA):
+ return( "PKCS5 - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT):
+ return( "PKCS5 - Unexpected ASN.1 data" );
+ case -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE):
+ return( "PKCS5 - Requested encryption or digest alg not available" );
+ case -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH):
+ return( "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */
#if defined(MBEDTLS_RSA_C)
- if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
- mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
- if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the validity check of the library" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
- if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
- if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
- if( use_ret == -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) )
- mbedtls_snprintf( buf, buflen, "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
- if( use_ret == -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "RSA - RSA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA):
+ return( "RSA - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_RSA_INVALID_PADDING):
+ return( "RSA - Input data contains invalid padding and is rejected" );
+ case -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED):
+ return( "RSA - Something failed during generation of a key" );
+ case -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED):
+ return( "RSA - Key failed to pass the validity check of the library" );
+ case -(MBEDTLS_ERR_RSA_PUBLIC_FAILED):
+ return( "RSA - The public key operation failed" );
+ case -(MBEDTLS_ERR_RSA_PRIVATE_FAILED):
+ return( "RSA - The private key operation failed" );
+ case -(MBEDTLS_ERR_RSA_VERIFY_FAILED):
+ return( "RSA - The PKCS#1 verification failed" );
+ case -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE):
+ return( "RSA - The output buffer for decryption is not large enough" );
+ case -(MBEDTLS_ERR_RSA_RNG_FAILED):
+ return( "RSA - The random generator failed to generate non-zeros" );
+ case -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION):
+ return( "RSA - The implementation does not offer the requested operation, for example, because of security violations or lack of functionality" );
+ case -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED):
+ return( "RSA - RSA hardware accelerator failed" );
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_SSL_TLS_C)
- if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
- mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
- mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
- mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
- mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
- mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
- if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
- {
- mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
- return;
- }
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
- mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
- mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
- mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
- if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
- if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
- mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
- mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
- mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
- if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
- mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
- mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
- mbedtls_snprintf( buf, buflen, "SSL - No data of requested type currently available on underlying transport" );
- if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
- mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
- if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
- mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
- mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
- if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) )
- mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" );
- if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) )
- mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" );
- if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) )
- mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
- if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
- if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) )
- mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" );
- if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) )
- mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" );
- if( use_ret == -(MBEDTLS_ERR_SSL_BAD_CONFIG) )
- mbedtls_snprintf( buf, buflen, "SSL - Invalid value in SSL config" );
+ case -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE):
+ return( "SSL - The requested feature is not available" );
+ case -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA):
+ return( "SSL - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_SSL_INVALID_MAC):
+ return( "SSL - Verification of the message MAC failed" );
+ case -(MBEDTLS_ERR_SSL_INVALID_RECORD):
+ return( "SSL - An invalid SSL record was received" );
+ case -(MBEDTLS_ERR_SSL_CONN_EOF):
+ return( "SSL - The connection indicated an EOF" );
+ case -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER):
+ return( "SSL - An unknown cipher was received" );
+ case -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN):
+ return( "SSL - The server has no ciphersuites in common with the client" );
+ case -(MBEDTLS_ERR_SSL_NO_RNG):
+ return( "SSL - No RNG was provided to the SSL module" );
+ case -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE):
+ return( "SSL - No client certification received from the client, but required by the authentication mode" );
+ case -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE):
+ return( "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
+ case -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED):
+ return( "SSL - The own certificate is not set, but needed by the server" );
+ case -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED):
+ return( "SSL - The own private key or pre-shared key is not set, but needed" );
+ case -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED):
+ return( "SSL - No CA Chain is set, but required to operate" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE):
+ return( "SSL - An unexpected message was received from our peer" );
+ case -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE):
+ return( "SSL - A fatal alert message was received from our peer" );
+ case -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED):
+ return( "SSL - Verification of our peer failed" );
+ case -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY):
+ return( "SSL - The peer notified us that the connection is going to be closed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO):
+ return( "SSL - Processing of the ClientHello handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO):
+ return( "SSL - Processing of the ServerHello handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE):
+ return( "SSL - Processing of the Certificate handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST):
+ return( "SSL - Processing of the CertificateRequest handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE):
+ return( "SSL - Processing of the ServerKeyExchange handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE):
+ return( "SSL - Processing of the ServerHelloDone handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS):
+ return( "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY):
+ return( "SSL - Processing of the CertificateVerify handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC):
+ return( "SSL - Processing of the ChangeCipherSpec handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED):
+ return( "SSL - Processing of the Finished handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_ALLOC_FAILED):
+ return( "SSL - Memory allocation failed" );
+ case -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED):
+ return( "SSL - Hardware acceleration function returned with error" );
+ case -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH):
+ return( "SSL - Hardware acceleration function skipped / left alone data" );
+ case -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED):
+ return( "SSL - Processing of the compression / decompression failed" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION):
+ return( "SSL - Handshake protocol not within min/max boundaries" );
+ case -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET):
+ return( "SSL - Processing of the NewSessionTicket handshake message failed" );
+ case -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED):
+ return( "SSL - Session ticket has expired" );
+ case -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH):
+ return( "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
+ case -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY):
+ return( "SSL - Unknown identity received (eg, PSK identity)" );
+ case -(MBEDTLS_ERR_SSL_INTERNAL_ERROR):
+ return( "SSL - Internal error (eg, unexpected failure in lower-level module)" );
+ case -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING):
+ return( "SSL - A counter would wrap (eg, too many messages exchanged)" );
+ case -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO):
+ return( "SSL - Unexpected message at ServerHello in renegotiation" );
+ case -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED):
+ return( "SSL - DTLS client must retry for hello verification" );
+ case -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL):
+ return( "SSL - A buffer is too small to receive or write a message" );
+ case -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE):
+ return( "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
+ case -(MBEDTLS_ERR_SSL_WANT_READ):
+ return( "SSL - No data of requested type currently available on underlying transport" );
+ case -(MBEDTLS_ERR_SSL_WANT_WRITE):
+ return( "SSL - Connection requires a write call" );
+ case -(MBEDTLS_ERR_SSL_TIMEOUT):
+ return( "SSL - The operation timed out" );
+ case -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT):
+ return( "SSL - The client initiated a reconnect from the same port" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD):
+ return( "SSL - Record header looks valid but is not expected" );
+ case -(MBEDTLS_ERR_SSL_NON_FATAL):
+ return( "SSL - The alert message received indicates a non-fatal error" );
+ case -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH):
+ return( "SSL - Couldn't set the hash for verifying CertificateVerify" );
+ case -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING):
+ return( "SSL - Internal-only message signaling that further message-processing should be done" );
+ case -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS):
+ return( "SSL - The asynchronous operation is not completed yet" );
+ case -(MBEDTLS_ERR_SSL_EARLY_MESSAGE):
+ return( "SSL - Internal-only message signaling that a message arrived early" );
+ case -(MBEDTLS_ERR_SSL_UNEXPECTED_CID):
+ return( "SSL - An encrypted DTLS-frame with an unexpected CID was received" );
+ case -(MBEDTLS_ERR_SSL_VERSION_MISMATCH):
+ return( "SSL - An operation failed due to an unexpected version or configuration" );
+ case -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS):
+ return( "SSL - A cryptographic operation is in progress. Try again later" );
+ case -(MBEDTLS_ERR_SSL_BAD_CONFIG):
+ return( "SSL - Invalid value in SSL config" );
#endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
- if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
- mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
- mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
- mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
- mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
- mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
- mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
- mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
- if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
- if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
- mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
- if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
- if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
- if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
- if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
- mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" );
+ case -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE):
+ return( "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_OID):
+ return( "X509 - Requested OID is unknown" );
+ case -(MBEDTLS_ERR_X509_INVALID_FORMAT):
+ return( "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
+ case -(MBEDTLS_ERR_X509_INVALID_VERSION):
+ return( "X509 - The CRT/CRL/CSR version element is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_SERIAL):
+ return( "X509 - The serial tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_ALG):
+ return( "X509 - The algorithm tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_NAME):
+ return( "X509 - The name tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_DATE):
+ return( "X509 - The date tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_SIGNATURE):
+ return( "X509 - The signature tag or value invalid" );
+ case -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS):
+ return( "X509 - The extension tag or value is invalid" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_VERSION):
+ return( "X509 - CRT/CRL/CSR has an unsupported version number" );
+ case -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG):
+ return( "X509 - Signature algorithm (oid) is unsupported" );
+ case -(MBEDTLS_ERR_X509_SIG_MISMATCH):
+ return( "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
+ case -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED):
+ return( "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
+ case -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT):
+ return( "X509 - Format not recognized as DER or PEM" );
+ case -(MBEDTLS_ERR_X509_BAD_INPUT_DATA):
+ return( "X509 - Input invalid" );
+ case -(MBEDTLS_ERR_X509_ALLOC_FAILED):
+ return( "X509 - Allocation of memory failed" );
+ case -(MBEDTLS_ERR_X509_FILE_IO_ERROR):
+ return( "X509 - Read/write of file failed" );
+ case -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL):
+ return( "X509 - Destination buffer is too small" );
+ case -(MBEDTLS_ERR_X509_FATAL_ERROR):
+ return( "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
- // END generated code
+ /* End Auto-Generated Code. */
- if( strlen( buf ) == 0 )
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+ default:
+ break;
}
- use_ret = ret & ~0xFF80;
-
- if( use_ret == 0 )
- return;
-
- // If high level code is present, make a concatenation between both
- // error strings.
- //
- len = strlen( buf );
+ return( NULL );
+}
- if( len > 0 )
- {
- if( buflen - len < 5 )
- return;
+const char * mbedtls_low_level_strerr( int error_code )
+{
+ int low_level_error_code;
- mbedtls_snprintf( buf + len, buflen - len, " : " );
+ if( error_code < 0 )
+ error_code = -error_code;
- buf += len + 3;
- buflen -= len + 3;
- }
+ /* Extract the low-level part from the error code. */
+ low_level_error_code = error_code & ~0xFF80;
- // Low level error codes
- //
- // BEGIN generated code
+ switch( low_level_error_code )
+ {
+ /* Begin Auto-Generated Code. */
#if defined(MBEDTLS_AES_C)
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
- if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_AES_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "AES - Invalid input data" );
- if( use_ret == -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "AES - Feature not available. For example, an unsupported AES key size" );
- if( use_ret == -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "AES - AES hardware accelerator failed" );
+ case -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH):
+ return( "AES - Invalid key length" );
+ case -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH):
+ return( "AES - Invalid data input length" );
+ case -(MBEDTLS_ERR_AES_BAD_INPUT_DATA):
+ return( "AES - Invalid input data" );
+ case -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE):
+ return( "AES - Feature not available. For example, an unsupported AES key size" );
+ case -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED):
+ return( "AES - AES hardware accelerator failed" );
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_ARC4_C)
- if( use_ret == -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ARC4 - ARC4 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED):
+ return( "ARC4 - ARC4 hardware accelerator failed" );
#endif /* MBEDTLS_ARC4_C */
#if defined(MBEDTLS_ARIA_C)
- if( use_ret == -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "ARIA - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "ARIA - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "ARIA - Feature not available. For example, an unsupported ARIA key size" );
- if( use_ret == -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "ARIA - ARIA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA):
+ return( "ARIA - Bad input data" );
+ case -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH):
+ return( "ARIA - Invalid data input length" );
+ case -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE):
+ return( "ARIA - Feature not available. For example, an unsupported ARIA key size" );
+ case -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED):
+ return( "ARIA - ARIA hardware accelerator failed" );
#endif /* MBEDTLS_ARIA_C */
#if defined(MBEDTLS_ASN1_PARSE_C)
- if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
- mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
- if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
+ case -(MBEDTLS_ERR_ASN1_OUT_OF_DATA):
+ return( "ASN1 - Out of data when parsing an ASN1 data structure" );
+ case -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG):
+ return( "ASN1 - ASN1 tag was of an unexpected value" );
+ case -(MBEDTLS_ERR_ASN1_INVALID_LENGTH):
+ return( "ASN1 - Error when trying to determine the length or invalid length" );
+ case -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH):
+ return( "ASN1 - Actual length differs from expected length" );
+ case -(MBEDTLS_ERR_ASN1_INVALID_DATA):
+ return( "ASN1 - Data is invalid" );
+ case -(MBEDTLS_ERR_ASN1_ALLOC_FAILED):
+ return( "ASN1 - Memory allocation failed" );
+ case -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL):
+ return( "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* MBEDTLS_ASN1_PARSE_C */
#if defined(MBEDTLS_BASE64_C)
- if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
- if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
+ case -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL):
+ return( "BASE64 - Output buffer too small" );
+ case -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER):
+ return( "BASE64 - Invalid character in input" );
#endif /* MBEDTLS_BASE64_C */
#if defined(MBEDTLS_BIGNUM_C)
- if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
- if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
- if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
- if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
- if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
- mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
+ case -(MBEDTLS_ERR_MPI_FILE_IO_ERROR):
+ return( "BIGNUM - An error occurred while reading from or writing to a file" );
+ case -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA):
+ return( "BIGNUM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_MPI_INVALID_CHARACTER):
+ return( "BIGNUM - There is an invalid character in the digit string" );
+ case -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL):
+ return( "BIGNUM - The buffer is too small to write to" );
+ case -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE):
+ return( "BIGNUM - The input arguments are negative or result in illegal output" );
+ case -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO):
+ return( "BIGNUM - The input argument for division is zero, which is not allowed" );
+ case -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE):
+ return( "BIGNUM - The input arguments are not acceptable" );
+ case -(MBEDTLS_ERR_MPI_ALLOC_FAILED):
+ return( "BIGNUM - Memory allocation failed" );
#endif /* MBEDTLS_BIGNUM_C */
#if defined(MBEDTLS_BLOWFISH_C)
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "BLOWFISH - Blowfish hardware accelerator failed" );
+ case -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA):
+ return( "BLOWFISH - Bad input data" );
+ case -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH):
+ return( "BLOWFISH - Invalid data input length" );
+ case -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED):
+ return( "BLOWFISH - Blowfish hardware accelerator failed" );
#endif /* MBEDTLS_BLOWFISH_C */
#if defined(MBEDTLS_CAMELLIA_C)
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Bad input data" );
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
- if( use_ret == -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CAMELLIA - Camellia hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA):
+ return( "CAMELLIA - Bad input data" );
+ case -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH):
+ return( "CAMELLIA - Invalid data input length" );
+ case -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED):
+ return( "CAMELLIA - Camellia hardware accelerator failed" );
#endif /* MBEDTLS_CAMELLIA_C */
#if defined(MBEDTLS_CCM_C)
- if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to the function" );
- if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
- if( use_ret == -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CCM_BAD_INPUT):
+ return( "CCM - Bad input parameters to the function" );
+ case -(MBEDTLS_ERR_CCM_AUTH_FAILED):
+ return( "CCM - Authenticated decryption failed" );
+ case -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED):
+ return( "CCM - CCM hardware accelerator failed" );
#endif /* MBEDTLS_CCM_C */
#if defined(MBEDTLS_CHACHA20_C)
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" );
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
- if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA):
+ return( "CHACHA20 - Invalid input parameter(s)" );
+ case -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE):
+ return( "CHACHA20 - Feature not available. For example, s part of the API is not implemented" );
+ case -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED):
+ return( "CHACHA20 - Chacha20 hardware accelerator failed" );
#endif /* MBEDTLS_CHACHA20_C */
#if defined(MBEDTLS_CHACHAPOLY_C)
- if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) )
- mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" );
- if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
+ case -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE):
+ return( "CHACHAPOLY - The requested operation is not permitted in the current state" );
+ case -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED):
+ return( "CHACHAPOLY - Authenticated decryption failed: data was not authentic" );
#endif /* MBEDTLS_CHACHAPOLY_C */
#if defined(MBEDTLS_CMAC_C)
- if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" );
+ case -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED):
+ return( "CMAC - CMAC hardware accelerator failed" );
#endif /* MBEDTLS_CMAC_C */
#if defined(MBEDTLS_CTR_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The requested random buffer length is too big" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - The input (entropy + additional data) is too large" );
- if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read or write error in file" );
+ case -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED):
+ return( "CTR_DRBG - The entropy source failed" );
+ case -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG):
+ return( "CTR_DRBG - The requested random buffer length is too big" );
+ case -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG):
+ return( "CTR_DRBG - The input (entropy + additional data) is too large" );
+ case -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR):
+ return( "CTR_DRBG - Read or write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */
#if defined(MBEDTLS_DES_C)
- if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
- if( use_ret == -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "DES - DES hardware accelerator failed" );
+ case -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH):
+ return( "DES - The data input has an invalid length" );
+ case -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED):
+ return( "DES - DES hardware accelerator failed" );
#endif /* MBEDTLS_DES_C */
#if defined(MBEDTLS_ENTROPY_C)
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
- if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
+ case -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED):
+ return( "ENTROPY - Critical entropy source failure" );
+ case -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES):
+ return( "ENTROPY - No more sources can be added" );
+ case -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED):
+ return( "ENTROPY - No sources have been added to poll" );
+ case -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE):
+ return( "ENTROPY - No strong sources have been added to poll" );
+ case -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR):
+ return( "ENTROPY - Read/write error in file" );
#endif /* MBEDTLS_ENTROPY_C */
+#if defined(MBEDTLS_ERROR_C)
+ case -(MBEDTLS_ERR_ERROR_GENERIC_ERROR):
+ return( "ERROR - Generic error" );
+ case -(MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED):
+ return( "ERROR - This is a bug in the library" );
+#endif /* MBEDTLS_ERROR_C */
+
#if defined(MBEDTLS_GCM_C)
- if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
- mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
- if( use_ret == -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "GCM - GCM hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
- mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_GCM_AUTH_FAILED):
+ return( "GCM - Authenticated decryption failed" );
+ case -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED):
+ return( "GCM - GCM hardware accelerator failed" );
+ case -(MBEDTLS_ERR_GCM_BAD_INPUT):
+ return( "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_HKDF_C)
- if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA):
+ return( "HKDF - Bad input parameters to function" );
#endif /* MBEDTLS_HKDF_C */
#if defined(MBEDTLS_HMAC_DRBG_C)
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
- if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
- mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG):
+ return( "HMAC_DRBG - Too many random requested in single call" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG):
+ return( "HMAC_DRBG - Input too large (Entropy + additional)" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR):
+ return( "HMAC_DRBG - Read/write error in file" );
+ case -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED):
+ return( "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */
#if defined(MBEDTLS_MD2_C)
- if( use_ret == -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD2 - MD2 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED):
+ return( "MD2 - MD2 hardware accelerator failed" );
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
- if( use_ret == -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD4 - MD4 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED):
+ return( "MD4 - MD4 hardware accelerator failed" );
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
- if( use_ret == -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "MD5 - MD5 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED):
+ return( "MD5 - MD5 hardware accelerator failed" );
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_NET_C)
- if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
- if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
- if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
- mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
- if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
- mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
- if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
- if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
- mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
- if( use_ret == -(MBEDTLS_ERR_NET_POLL_FAILED) )
- mbedtls_snprintf( buf, buflen, "NET - Polling the net context failed" );
- if( use_ret == -(MBEDTLS_ERR_NET_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "NET - Input invalid" );
+ case -(MBEDTLS_ERR_NET_SOCKET_FAILED):
+ return( "NET - Failed to open a socket" );
+ case -(MBEDTLS_ERR_NET_CONNECT_FAILED):
+ return( "NET - The connection to the given server / port failed" );
+ case -(MBEDTLS_ERR_NET_BIND_FAILED):
+ return( "NET - Binding of the socket failed" );
+ case -(MBEDTLS_ERR_NET_LISTEN_FAILED):
+ return( "NET - Could not listen on the socket" );
+ case -(MBEDTLS_ERR_NET_ACCEPT_FAILED):
+ return( "NET - Could not accept the incoming connection" );
+ case -(MBEDTLS_ERR_NET_RECV_FAILED):
+ return( "NET - Reading information from the socket failed" );
+ case -(MBEDTLS_ERR_NET_SEND_FAILED):
+ return( "NET - Sending information through the socket failed" );
+ case -(MBEDTLS_ERR_NET_CONN_RESET):
+ return( "NET - Connection was reset by peer" );
+ case -(MBEDTLS_ERR_NET_UNKNOWN_HOST):
+ return( "NET - Failed to get an IP address for the given hostname" );
+ case -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL):
+ return( "NET - Buffer is too small to hold the data" );
+ case -(MBEDTLS_ERR_NET_INVALID_CONTEXT):
+ return( "NET - The context is invalid, eg because it was free()ed" );
+ case -(MBEDTLS_ERR_NET_POLL_FAILED):
+ return( "NET - Polling the net context failed" );
+ case -(MBEDTLS_ERR_NET_BAD_INPUT_DATA):
+ return( "NET - Input invalid" );
#endif /* MBEDTLS_NET_C */
#if defined(MBEDTLS_OID_C)
- if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
- mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
- if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
- mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
+ case -(MBEDTLS_ERR_OID_NOT_FOUND):
+ return( "OID - OID is not found" );
+ case -(MBEDTLS_ERR_OID_BUF_TOO_SMALL):
+ return( "OID - output buffer is too small" );
#endif /* MBEDTLS_OID_C */
#if defined(MBEDTLS_PADLOCK_C)
- if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
- mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
+ case -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED):
+ return( "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */
#if defined(MBEDTLS_PLATFORM_C)
- if( use_ret == -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "PLATFORM - Hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED) )
- mbedtls_snprintf( buf, buflen, "PLATFORM - The requested feature is not supported by the platform" );
+ case -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED):
+ return( "PLATFORM - Hardware accelerator failed" );
+ case -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED):
+ return( "PLATFORM - The requested feature is not supported by the platform" );
#endif /* MBEDTLS_PLATFORM_C */
#if defined(MBEDTLS_POLY1305_C)
- if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" );
- if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
- if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA):
+ return( "POLY1305 - Invalid input parameter(s)" );
+ case -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE):
+ return( "POLY1305 - Feature not available. For example, s part of the API is not implemented" );
+ case -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED):
+ return( "POLY1305 - Poly1305 hardware accelerator failed" );
#endif /* MBEDTLS_POLY1305_C */
#if defined(MBEDTLS_RIPEMD160_C)
- if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED):
+ return( "RIPEMD160 - RIPEMD160 hardware accelerator failed" );
#endif /* MBEDTLS_RIPEMD160_C */
#if defined(MBEDTLS_SHA1_C)
- if( use_ret == -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA1 - SHA-1 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED):
+ return( "SHA1 - SHA-1 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA):
+ return( "SHA1 - SHA-1 input data was malformed" );
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
- if( use_ret == -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA256 - SHA-256 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED):
+ return( "SHA256 - SHA-256 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA):
+ return( "SHA256 - SHA-256 input data was malformed" );
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
- if( use_ret == -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 hardware accelerator failed" );
- if( use_ret == -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "SHA512 - SHA-512 input data was malformed" );
+ case -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED):
+ return( "SHA512 - SHA-512 hardware accelerator failed" );
+ case -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA):
+ return( "SHA512 - SHA-512 input data was malformed" );
#endif /* MBEDTLS_SHA512_C */
#if defined(MBEDTLS_THREADING_C)
- if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
- mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
- mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
- if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
- mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
+ case -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE):
+ return( "THREADING - The selected feature is not available" );
+ case -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA):
+ return( "THREADING - Bad input parameters to function" );
+ case -(MBEDTLS_ERR_THREADING_MUTEX_ERROR):
+ return( "THREADING - Locking / unlocking / free failed with error code" );
#endif /* MBEDTLS_THREADING_C */
#if defined(MBEDTLS_XTEA_C)
- if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
- mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
- if( use_ret == -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED) )
- mbedtls_snprintf( buf, buflen, "XTEA - XTEA hardware accelerator failed" );
+ case -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH):
+ return( "XTEA - The data input has an invalid length" );
+ case -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED):
+ return( "XTEA - XTEA hardware accelerator failed" );
#endif /* MBEDTLS_XTEA_C */
- // END generated code
+ /* End Auto-Generated Code. */
+
+ default:
+ break;
+ }
+
+ return( NULL );
+}
+
+void mbedtls_strerror( int ret, char *buf, size_t buflen )
+{
+ size_t len;
+ int use_ret;
+ const char * high_level_error_description = NULL;
+ const char * low_level_error_description = NULL;
+
+ if( buflen == 0 )
+ return;
+
+ memset( buf, 0x00, buflen );
+
+ if( ret < 0 )
+ ret = -ret;
+
+ if( ret & 0xFF80 )
+ {
+ use_ret = ret & 0xFF80;
+
+ // Translate high level error code.
+ high_level_error_description = mbedtls_high_level_strerr( ret );
+
+ if( high_level_error_description == NULL )
+ mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret );
+ else
+ mbedtls_snprintf( buf, buflen, "%s", high_level_error_description );
+
+#if defined(MBEDTLS_SSL_TLS_C)
+ // Early return in case of a fatal error - do not try to translate low
+ // level code.
+ if(use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE))
+ return;
+#endif /* MBEDTLS_SSL_TLS_C */
+ }
- if( strlen( buf ) != 0 )
+ use_ret = ret & ~0xFF80;
+
+ if( use_ret == 0 )
return;
- mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
+ // If high level code is present, make a concatenation between both
+ // error strings.
+ //
+ len = strlen( buf );
+
+ if( len > 0 )
+ {
+ if( buflen - len < 5 )
+ return;
+
+ mbedtls_snprintf( buf + len, buflen - len, " : " );
+
+ buf += len + 3;
+ buflen -= len + 3;
+ }
+
+ // Translate low level error code.
+ low_level_error_description = mbedtls_low_level_strerr( ret );
+
+ if( low_level_error_description == NULL )
+ mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", (unsigned int) use_ret );
+ else
+ mbedtls_snprintf( buf, buflen, "%s", low_level_error_description );
}
#else /* MBEDTLS_ERROR_C */
@@ -941,4 +973,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
#endif /* MBEDTLS_ERROR_C */
+#if defined(MBEDTLS_TEST_HOOKS)
+void (*mbedtls_test_hook_error_add)( int, int, const char *, int );
+#endif
+
#endif /* MBEDTLS_ERROR_C || MBEDTLS_ERROR_STRERROR_DUMMY */
diff --git a/thirdparty/mbedtls/library/gcm.c b/thirdparty/mbedtls/library/gcm.c
index 441ed69a82..43a5e1bec6 100644
--- a/thirdparty/mbedtls/library/gcm.c
+++ b/thirdparty/mbedtls/library/gcm.c
@@ -2,13 +2,7 @@
* NIST SP800-38D compliant GCM implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -54,16 +27,13 @@
* [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_GCM_C)
#include "mbedtls/gcm.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -89,43 +59,6 @@
MBEDTLS_INTERNAL_VALIDATE( cond )
/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE( n, b, i ) \
-{ \
- ( b )[( i ) ] = (unsigned char) ( ( (n) >> 56 ) & 0xff ); \
- ( b )[( i ) + 1] = (unsigned char) ( ( (n) >> 48 ) & 0xff ); \
- ( b )[( i ) + 2] = (unsigned char) ( ( (n) >> 40 ) & 0xff ); \
- ( b )[( i ) + 3] = (unsigned char) ( ( (n) >> 32 ) & 0xff ); \
- ( b )[( i ) + 4] = (unsigned char) ( ( (n) >> 24 ) & 0xff ); \
- ( b )[( i ) + 5] = (unsigned char) ( ( (n) >> 16 ) & 0xff ); \
- ( b )[( i ) + 6] = (unsigned char) ( ( (n) >> 8 ) & 0xff ); \
- ( b )[( i ) + 7] = (unsigned char) ( ( (n) ) & 0xff ); \
-}
-#endif
-
-/*
* Initialize a context
*/
void mbedtls_gcm_init( mbedtls_gcm_context *ctx )
@@ -155,12 +88,12 @@ static int gcm_gen_table( mbedtls_gcm_context *ctx )
return( ret );
/* pack h as two 64-bits ints, big-endian */
- GET_UINT32_BE( hi, h, 0 );
- GET_UINT32_BE( lo, h, 4 );
+ hi = MBEDTLS_GET_UINT32_BE( h, 0 );
+ lo = MBEDTLS_GET_UINT32_BE( h, 4 );
vh = (uint64_t) hi << 32 | lo;
- GET_UINT32_BE( hi, h, 8 );
- GET_UINT32_BE( lo, h, 12 );
+ hi = MBEDTLS_GET_UINT32_BE( h, 8 );
+ lo = MBEDTLS_GET_UINT32_BE( h, 12 );
vl = (uint64_t) hi << 32 | lo;
/* 8 = 1000 corresponds to 1 in GF(2^128) */
@@ -207,14 +140,15 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx,
const unsigned char *key,
unsigned int keybits )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( key != NULL );
GCM_VALIDATE_RET( keybits == 128 || keybits == 192 || keybits == 256 );
- cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB );
+ cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
+ MBEDTLS_MODE_ECB );
if( cipher_info == NULL )
return( MBEDTLS_ERR_GCM_BAD_INPUT );
@@ -266,10 +200,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) {
unsigned char h[16];
- PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
- PUT_UINT32_BE( ctx->HH[8], h, 4 );
- PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
- PUT_UINT32_BE( ctx->HL[8], h, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HH[8], h, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->HL[8], h, 12 );
mbedtls_aesni_gcm_mult( output, x, h );
return;
@@ -284,7 +218,7 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
for( i = 15; i >= 0; i-- )
{
lo = x[i] & 0xf;
- hi = x[i] >> 4;
+ hi = ( x[i] >> 4 ) & 0xf;
if( i != 15 )
{
@@ -305,10 +239,10 @@ static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16],
zl ^= ctx->HL[hi];
}
- PUT_UINT32_BE( zh >> 32, output, 0 );
- PUT_UINT32_BE( zh, output, 4 );
- PUT_UINT32_BE( zl >> 32, output, 8 );
- PUT_UINT32_BE( zl, output, 12 );
+ MBEDTLS_PUT_UINT32_BE( zh >> 32, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( zh, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( zl >> 32, output, 8 );
+ MBEDTLS_PUT_UINT32_BE( zl, output, 12 );
}
int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
@@ -318,7 +252,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
const unsigned char *add,
size_t add_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char work_buf[16];
size_t i;
const unsigned char *p;
@@ -354,7 +288,7 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
{
memset( work_buf, 0x00, 16 );
iv_bits = (uint64_t)iv_len * 8;
- PUT_UINT64_BE( iv_bits, work_buf, 8 );
+ MBEDTLS_PUT_UINT64_BE( iv_bits, work_buf, 8 );
p = iv;
while( iv_len > 0 )
@@ -376,8 +310,8 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx,
gcm_mult( ctx, ctx->y, ctx->y );
}
- if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr,
- &olen ) ) != 0 )
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16,
+ ctx->base_ectr, &olen ) ) != 0 )
{
return( ret );
}
@@ -405,7 +339,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char ectr[16];
size_t i;
const unsigned char *p;
@@ -487,10 +421,10 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
{
memset( work_buf, 0x00, 16 );
- PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
- PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
- PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
- PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 );
+ MBEDTLS_PUT_UINT32_BE( ( orig_len ), work_buf, 12 );
for( i = 0; i < 16; i++ )
ctx->buf[i] ^= work_buf[i];
@@ -516,7 +450,7 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx,
size_t tag_len,
unsigned char *tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
GCM_VALIDATE_RET( ctx != NULL );
GCM_VALIDATE_RET( iv != NULL );
@@ -548,7 +482,7 @@ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char check_tag[16];
size_t i;
int diff;
@@ -598,10 +532,10 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx )
*/
#define MAX_TESTS 6
-static const int key_index[MAX_TESTS] =
+static const int key_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
-static const unsigned char key[MAX_TESTS][32] =
+static const unsigned char key_test_data[MAX_TESTS][32] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -613,13 +547,13 @@ static const unsigned char key[MAX_TESTS][32] =
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 },
};
-static const size_t iv_len[MAX_TESTS] =
+static const size_t iv_len_test_data[MAX_TESTS] =
{ 12, 12, 12, 12, 8, 60 };
-static const int iv_index[MAX_TESTS] =
+static const int iv_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 2 };
-static const unsigned char iv[MAX_TESTS][64] =
+static const unsigned char iv_test_data[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
@@ -635,13 +569,13 @@ static const unsigned char iv[MAX_TESTS][64] =
0xa6, 0x37, 0xb3, 0x9b },
};
-static const size_t add_len[MAX_TESTS] =
+static const size_t add_len_test_data[MAX_TESTS] =
{ 0, 0, 0, 20, 20, 20 };
-static const int add_index[MAX_TESTS] =
+static const int add_index_test_data[MAX_TESTS] =
{ 0, 0, 0, 1, 1, 1 };
-static const unsigned char additional[MAX_TESTS][64] =
+static const unsigned char additional_test_data[MAX_TESTS][64] =
{
{ 0x00 },
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
@@ -649,13 +583,13 @@ static const unsigned char additional[MAX_TESTS][64] =
0xab, 0xad, 0xda, 0xd2 },
};
-static const size_t pt_len[MAX_TESTS] =
+static const size_t pt_len_test_data[MAX_TESTS] =
{ 0, 16, 64, 60, 60, 60 };
-static const int pt_index[MAX_TESTS] =
+static const int pt_index_test_data[MAX_TESTS] =
{ 0, 0, 1, 1, 1, 1 };
-static const unsigned char pt[MAX_TESTS][64] =
+static const unsigned char pt_test_data[MAX_TESTS][64] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -669,7 +603,7 @@ static const unsigned char pt[MAX_TESTS][64] =
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 },
};
-static const unsigned char ct[MAX_TESTS * 3][64] =
+static const unsigned char ct_test_data[MAX_TESTS * 3][64] =
{
{ 0x00 },
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
@@ -778,7 +712,7 @@ static const unsigned char ct[MAX_TESTS * 3][64] =
0x44, 0xae, 0x7e, 0x3f },
};
-static const unsigned char tag[MAX_TESTS * 3][16] =
+static const unsigned char tag_test_data[MAX_TESTS * 3][16] =
{
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a },
@@ -838,7 +772,8 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "enc" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
/*
* AES-192 is an optional feature that may be unavailable when
@@ -856,15 +791,28 @@ int mbedtls_gcm_self_test( int verbose )
}
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- pt[pt_index[i]], buf, 16, tag_buf );
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf, 16, tag_buf );
+#if defined(MBEDTLS_GCM_ALT)
+ /* Allow alternative implementations to only support 12-byte nonces. */
+ if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED &&
+ iv_len_test_data[i] != 12 )
+ {
+ mbedtls_printf( "skipped\n" );
+ break;
+ }
+#endif /* defined(MBEDTLS_GCM_ALT) */
if( ret != 0 )
goto exit;
- if ( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if ( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -881,22 +829,26 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d (%s): ",
key_len, i, "dec" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT,
- pt_len[i],
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i],
- ct[j * 6 + i], buf, 16, tag_buf );
+ pt_len_test_data[i],
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i],
+ ct_test_data[j * 6 + i], buf, 16, tag_buf );
if( ret != 0 )
goto exit;
- if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -913,32 +865,40 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "enc" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
if( ret != 0 )
goto exit;
- if( pt_len[i] > 32 )
+ if( pt_len_test_data[i] > 32 )
{
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf );
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32,
+ pt_test_data[pt_index_test_data[i]],
+ buf );
if( ret != 0 )
goto exit;
- ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32,
- buf + 32 );
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ pt_test_data[pt_index_test_data[i]] + 32,
+ buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
- ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf );
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ pt_test_data[pt_index_test_data[i]],
+ buf );
if( ret != 0 )
goto exit;
}
@@ -947,8 +907,9 @@ int mbedtls_gcm_self_test( int verbose )
if( ret != 0 )
goto exit;
- if( memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, ct_test_data[j * 6 + i],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
@@ -965,32 +926,38 @@ int mbedtls_gcm_self_test( int verbose )
mbedtls_printf( " AES-GCM-%3d #%d split (%s): ",
key_len, i, "dec" );
- ret = mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]],
+ ret = mbedtls_gcm_setkey( &ctx, cipher,
+ key_test_data[key_index_test_data[i]],
key_len );
if( ret != 0 )
goto exit;
ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT,
- iv[iv_index[i]], iv_len[i],
- additional[add_index[i]], add_len[i] );
+ iv_test_data[iv_index_test_data[i]],
+ iv_len_test_data[i],
+ additional_test_data[add_index_test_data[i]],
+ add_len_test_data[i] );
if( ret != 0 )
goto exit;
- if( pt_len[i] > 32 )
+ if( pt_len_test_data[i] > 32 )
{
- size_t rest_len = pt_len[i] - 32;
- ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf );
+ size_t rest_len = pt_len_test_data[i] - 32;
+ ret = mbedtls_gcm_update( &ctx, 32, ct_test_data[j * 6 + i],
+ buf );
if( ret != 0 )
goto exit;
- ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32,
+ ret = mbedtls_gcm_update( &ctx, rest_len,
+ ct_test_data[j * 6 + i] + 32,
buf + 32 );
if( ret != 0 )
goto exit;
}
else
{
- ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i],
+ ret = mbedtls_gcm_update( &ctx, pt_len_test_data[i],
+ ct_test_data[j * 6 + i],
buf );
if( ret != 0 )
goto exit;
@@ -1000,8 +967,9 @@ int mbedtls_gcm_self_test( int verbose )
if( ret != 0 )
goto exit;
- if( memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 ||
- memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 )
+ if( memcmp( buf, pt_test_data[pt_index_test_data[i]],
+ pt_len_test_data[i] ) != 0 ||
+ memcmp( tag_buf, tag_test_data[j * 6 + i], 16 ) != 0 )
{
ret = 1;
goto exit;
diff --git a/thirdparty/mbedtls/library/havege.c b/thirdparty/mbedtls/library/havege.c
index 5e91f40d84..2a360a150c 100644
--- a/thirdparty/mbedtls/library/havege.c
+++ b/thirdparty/mbedtls/library/havege.c
@@ -2,13 +2,7 @@
* \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The HAVEGE RNG was designed by Andre Seznec in 2002.
@@ -51,11 +24,7 @@
* Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HAVEGE_C)
@@ -63,19 +32,9 @@
#include "mbedtls/timing.h"
#include "mbedtls/platform_util.h"
-#include <limits.h>
+#include <stdint.h>
#include <string.h>
-/* If int isn't capable of storing 2^32 distinct values, the code of this
- * module may cause a processor trap or a miscalculation. If int is more
- * than 32 bits, the code may not calculate the intended values. */
-#if INT_MIN + 1 != -0x7fffffff
-#error "The HAVEGE module requires int to be exactly 32 bits, with INT_MIN = -2^31."
-#endif
-#if UINT_MAX != 0xffffffff
-#error "The HAVEGE module requires unsigned to be exactly 32 bits."
-#endif
-
/* ------------------------------------------------------------------------
* On average, one iteration accesses two 8-word blocks in the havege WALK
* table, and generates 16 words in the RES array.
@@ -90,7 +49,7 @@
* ------------------------------------------------------------------------
*/
-#define SWAP(X,Y) { unsigned *T = (X); (X) = (Y); (Y) = T; }
+#define SWAP(X,Y) { uint32_t *T = (X); (X) = (Y); (Y) = T; }
#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1;
@@ -113,7 +72,7 @@
PTX = (PT1 >> 18) & 7; \
PT1 &= 0x1FFF; \
PT2 &= 0x1FFF; \
- CLK = (unsigned) mbedtls_timing_hardclock(); \
+ CLK = (uint32_t) mbedtls_timing_hardclock(); \
\
i = 0; \
A = &WALK[PT1 ]; RES[i++] ^= *A; \
@@ -136,7 +95,7 @@
\
IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \
*A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \
- *B = IN; CLK = (unsigned) mbedtls_timing_hardclock(); \
+ *B = IN; CLK = (uint32_t) mbedtls_timing_hardclock(); \
*C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \
*D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \
\
@@ -187,20 +146,20 @@
PT1 ^= (PT2 ^ 0x10) & 0x10; \
\
for( n++, i = 0; i < 16; i++ ) \
- POOL[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
+ hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i];
/*
* Entropy gathering function
*/
static void havege_fill( mbedtls_havege_state *hs )
{
- unsigned i, n = 0;
- unsigned U1, U2, *A, *B, *C, *D;
- unsigned PT1, PT2, *WALK, *POOL, RES[16];
- unsigned PTX, PTY, CLK, PTEST, IN;
+ size_t n = 0;
+ size_t i;
+ uint32_t U1, U2, *A, *B, *C, *D;
+ uint32_t PT1, PT2, *WALK, RES[16];
+ uint32_t PTX, PTY, CLK, PTEST, IN;
- WALK = (unsigned *) hs->WALK;
- POOL = (unsigned *) hs->pool;
+ WALK = hs->WALK;
PT1 = hs->PT1;
PT2 = hs->PT2;
@@ -249,7 +208,7 @@ void mbedtls_havege_free( mbedtls_havege_state *hs )
*/
int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
{
- int val;
+ uint32_t val;
size_t use_len;
mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng;
unsigned char *p = buf;
@@ -257,8 +216,8 @@ int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len )
while( len > 0 )
{
use_len = len;
- if( use_len > sizeof(int) )
- use_len = sizeof(int);
+ if( use_len > sizeof( val ) )
+ use_len = sizeof( val );
if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE )
havege_fill( hs );
diff --git a/thirdparty/mbedtls/library/hkdf.c b/thirdparty/mbedtls/library/hkdf.c
index 4a8bdfbe18..5013729d2a 100644
--- a/thirdparty/mbedtls/library/hkdf.c
+++ b/thirdparty/mbedtls/library/hkdf.c
@@ -2,13 +2,7 @@
* HKDF implementation -- RFC 5869
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,46 +15,22 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HKDF_C)
#include <string.h>
#include "mbedtls/hkdf.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt,
size_t salt_len, const unsigned char *ikm, size_t ikm_len,
const unsigned char *info, size_t info_len,
unsigned char *okm, size_t okm_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char prk[MBEDTLS_MD_MAX_SIZE];
ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk );
@@ -139,7 +109,7 @@ int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
n = okm_len / hash_len;
- if( (okm_len % hash_len) != 0 )
+ if( okm_len % hash_len != 0 )
{
n++;
}
@@ -155,11 +125,13 @@ int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk,
mbedtls_md_init( &ctx );
- if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 )
+ if( ( ret = mbedtls_md_setup( &ctx, md, 1 ) ) != 0 )
{
goto exit;
}
+ memset( t, 0, hash_len );
+
/*
* Compute T = T(1) | T(2) | T(3) | ... | T(N)
* Where T(N) is defined in RFC 5869 Section 2.3
diff --git a/thirdparty/mbedtls/library/hmac_drbg.c b/thirdparty/mbedtls/library/hmac_drbg.c
index b45d61616f..de9706885c 100644
--- a/thirdparty/mbedtls/library/hmac_drbg.c
+++ b/thirdparty/mbedtls/library/hmac_drbg.c
@@ -2,13 +2,7 @@
* HMAC_DRBG implementation (NIST SP 800-90)
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,16 +23,13 @@
* References below are based on rev. 1 (January 2012).
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_HMAC_DRBG_C)
#include "mbedtls/hmac_drbg.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -97,7 +67,7 @@ int mbedtls_hmac_drbg_update_ret( mbedtls_hmac_drbg_context *ctx,
unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1;
unsigned char sep[1];
unsigned char K[MBEDTLS_MD_MAX_SIZE];
- int ret;
+ int ret = MBEDTLS_ERR_MD_BAD_INPUT_DATA;
for( sep[0] = 0; sep[0] < rounds; sep[0]++ )
{
@@ -150,7 +120,7 @@ int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx,
const mbedtls_md_info_t * md_info,
const unsigned char *data, size_t data_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
return( ret );
@@ -186,7 +156,7 @@ static int hmac_drbg_reseed_core( mbedtls_hmac_drbg_context *ctx,
{
unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
{
size_t total_entropy_len;
@@ -278,7 +248,7 @@ int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx,
const unsigned char *custom,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t md_size;
if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 )
@@ -359,7 +329,7 @@ int mbedtls_hmac_drbg_random_with_add( void *p_rng,
unsigned char *output, size_t out_len,
const unsigned char *additional, size_t add_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info );
size_t left = out_len;
@@ -428,7 +398,7 @@ exit:
*/
int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng;
#if defined(MBEDTLS_THREADING_C)
@@ -468,7 +438,7 @@ void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx )
#if defined(MBEDTLS_FS_IO)
int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f;
unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ];
diff --git a/thirdparty/mbedtls/library/md.c b/thirdparty/mbedtls/library/md.c
index 867b91462d..a10a835634 100644
--- a/thirdparty/mbedtls/library/md.c
+++ b/thirdparty/mbedtls/library/md.c
@@ -1,18 +1,12 @@
/**
- * \file mbedtls_md.c
+ * \file md.c
*
* \brief Generic message digest wrapper for mbed TLS
*
* \author Adriaan de Jong <dejong@fox-it.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,40 +19,24 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD_C)
#include "mbedtls/md.h"
#include "mbedtls/md_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+
+#include "mbedtls/md2.h"
+#include "mbedtls/md4.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/ripemd160.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
@@ -74,6 +52,85 @@
#include <stdio.h>
#endif
+#if defined(MBEDTLS_MD2_C)
+const mbedtls_md_info_t mbedtls_md2_info = {
+ "MD2",
+ MBEDTLS_MD_MD2,
+ 16,
+ 16,
+};
+#endif
+
+#if defined(MBEDTLS_MD4_C)
+const mbedtls_md_info_t mbedtls_md4_info = {
+ "MD4",
+ MBEDTLS_MD_MD4,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_MD5_C)
+const mbedtls_md_info_t mbedtls_md5_info = {
+ "MD5",
+ MBEDTLS_MD_MD5,
+ 16,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_C)
+const mbedtls_md_info_t mbedtls_ripemd160_info = {
+ "RIPEMD160",
+ MBEDTLS_MD_RIPEMD160,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA1_C)
+const mbedtls_md_info_t mbedtls_sha1_info = {
+ "SHA1",
+ MBEDTLS_MD_SHA1,
+ 20,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA256_C)
+const mbedtls_md_info_t mbedtls_sha224_info = {
+ "SHA224",
+ MBEDTLS_MD_SHA224,
+ 28,
+ 64,
+};
+
+const mbedtls_md_info_t mbedtls_sha256_info = {
+ "SHA256",
+ MBEDTLS_MD_SHA256,
+ 32,
+ 64,
+};
+#endif
+
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+const mbedtls_md_info_t mbedtls_sha384_info = {
+ "SHA384",
+ MBEDTLS_MD_SHA384,
+ 48,
+ 128,
+};
+#endif
+
+const mbedtls_md_info_t mbedtls_sha512_info = {
+ "SHA512",
+ MBEDTLS_MD_SHA512,
+ 64,
+ 128,
+};
+#endif
+
/*
* Reminder: update profiles in x509_crt.c when adding a new hash!
*/
@@ -81,8 +138,10 @@ static const int supported_digests[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
MBEDTLS_MD_SHA384,
#endif
+#endif
#if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256,
@@ -150,8 +209,10 @@ const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
#endif
#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
if( !strcmp( "SHA384", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 );
+#endif
if( !strcmp( "SHA512", md_name ) )
return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
#endif
@@ -189,8 +250,10 @@ const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type )
return( &mbedtls_sha256_info );
#endif
#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_MD_SHA384:
return( &mbedtls_sha384_info );
+#endif
case MBEDTLS_MD_SHA512:
return( &mbedtls_sha512_info );
#endif
@@ -210,7 +273,54 @@ void mbedtls_md_free( mbedtls_md_context_t *ctx )
return;
if( ctx->md_ctx != NULL )
- ctx->md_info->ctx_free_func( ctx->md_ctx );
+ {
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_free( ctx->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_free( ctx->md_ctx );
+ break;
+#endif
+ default:
+ /* Shouldn't happen */
+ break;
+ }
+ mbedtls_free( ctx->md_ctx );
+ }
if( ctx->hmac_ctx != NULL )
{
@@ -232,7 +342,50 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst,
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
}
- dst->md_info->clone_func( dst->md_ctx, src->md_ctx );
+ switch( src->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ mbedtls_md2_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ mbedtls_md4_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ mbedtls_md5_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ mbedtls_ripemd160_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ mbedtls_sha1_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ mbedtls_sha256_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ mbedtls_sha512_clone( dst->md_ctx, src->md_ctx );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
return( 0 );
}
@@ -244,35 +397,127 @@ int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_
}
#endif
+#define ALLOC( type ) \
+ do { \
+ ctx->md_ctx = mbedtls_calloc( 1, sizeof( mbedtls_##type##_context ) ); \
+ if( ctx->md_ctx == NULL ) \
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED ); \
+ mbedtls_##type##_init( ctx->md_ctx ); \
+ } \
+ while( 0 )
+
int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac )
{
if( md_info == NULL || ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL )
- return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ ctx->md_info = md_info;
+ ctx->md_ctx = NULL;
+ ctx->hmac_ctx = NULL;
+
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ ALLOC( md2 );
+ break;
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ ALLOC( md4 );
+ break;
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ ALLOC( md5 );
+ break;
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ ALLOC( ripemd160 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ ALLOC( sha1 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ ALLOC( sha256 );
+ break;
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ ALLOC( sha512 );
+ break;
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
if( hmac != 0 )
{
ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size );
if( ctx->hmac_ctx == NULL )
{
- md_info->ctx_free_func( ctx->md_ctx );
+ mbedtls_md_free( ctx );
return( MBEDTLS_ERR_MD_ALLOC_FAILED );
}
}
- ctx->md_info = md_info;
-
return( 0 );
}
+#undef ALLOC
int mbedtls_md_starts( mbedtls_md_context_t *ctx )
{
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->starts_func( ctx->md_ctx ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_starts_ret( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 1 ) );
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_starts_ret( ctx->md_ctx, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen )
@@ -280,7 +525,43 @@ int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, si
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_update_ret( ctx->md_ctx, input, ilen ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
@@ -288,7 +569,43 @@ int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output )
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_finish_ret( ctx->md_ctx, output ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_finish_ret( ctx->md_ctx, output ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen,
@@ -297,13 +614,51 @@ int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, si
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( md_info->digest_func( input, ilen, output ) );
+ switch( md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_md2_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_md4_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_md5_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_ripemd160_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_sha1_ret( input, ilen, output ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+ return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
#if defined(MBEDTLS_FS_IO)
int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
FILE *f;
size_t n;
mbedtls_md_context_t ctx;
@@ -320,17 +675,17 @@ int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigne
if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 )
goto cleanup;
- if( ( ret = md_info->starts_func( ctx.md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( &ctx ) ) != 0 )
goto cleanup;
while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
- if( ( ret = md_info->update_func( ctx.md_ctx, buf, n ) ) != 0 )
+ if( ( ret = mbedtls_md_update( &ctx, buf, n ) ) != 0 )
goto cleanup;
if( ferror( f ) != 0 )
ret = MBEDTLS_ERR_MD_FILE_IO_ERROR;
else
- ret = md_info->finish_func( ctx.md_ctx, output );
+ ret = mbedtls_md_finish( &ctx, output );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -343,7 +698,7 @@ cleanup:
int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char sum[MBEDTLS_MD_MAX_SIZE];
unsigned char *ipad, *opad;
size_t i;
@@ -353,11 +708,11 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
if( keylen > (size_t) ctx->md_info->block_size )
{
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, key, keylen ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, key, keylen ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, sum ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, sum ) ) != 0 )
goto cleanup;
keylen = ctx->md_info->size;
@@ -376,10 +731,10 @@ int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key,
opad[i] = (unsigned char)( opad[i] ^ key[i] );
}
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
goto cleanup;
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, ipad,
+ ctx->md_info->block_size ) ) != 0 )
goto cleanup;
cleanup:
@@ -393,12 +748,12 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->update_func( ctx->md_ctx, input, ilen ) );
+ return( mbedtls_md_update( ctx, input, ilen ) );
}
int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
unsigned char *opad;
@@ -407,22 +762,22 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output )
opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size;
- if( ( ret = ctx->md_info->finish_func( ctx->md_ctx, tmp ) ) != 0 )
+ if( ( ret = mbedtls_md_finish( ctx, tmp ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, opad,
- ctx->md_info->block_size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, opad,
+ ctx->md_info->block_size ) ) != 0 )
return( ret );
- if( ( ret = ctx->md_info->update_func( ctx->md_ctx, tmp,
- ctx->md_info->size ) ) != 0 )
+ if( ( ret = mbedtls_md_update( ctx, tmp,
+ ctx->md_info->size ) ) != 0 )
return( ret );
- return( ctx->md_info->finish_func( ctx->md_ctx, output ) );
+ return( mbedtls_md_finish( ctx, output ) );
}
int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *ipad;
if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL )
@@ -430,10 +785,9 @@ int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx )
ipad = (unsigned char *) ctx->hmac_ctx;
- if( ( ret = ctx->md_info->starts_func( ctx->md_ctx ) ) != 0 )
+ if( ( ret = mbedtls_md_starts( ctx ) ) != 0 )
return( ret );
- return( ctx->md_info->update_func( ctx->md_ctx, ipad,
- ctx->md_info->block_size ) );
+ return( mbedtls_md_update( ctx, ipad, ctx->md_info->block_size ) );
}
int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
@@ -442,7 +796,7 @@ int mbedtls_md_hmac( const mbedtls_md_info_t *md_info,
unsigned char *output )
{
mbedtls_md_context_t ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
@@ -470,7 +824,43 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data )
if( ctx == NULL || ctx->md_info == NULL )
return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
- return( ctx->md_info->process_func( ctx->md_ctx, data ) );
+ switch( ctx->md_info->type )
+ {
+#if defined(MBEDTLS_MD2_C)
+ case MBEDTLS_MD_MD2:
+ return( mbedtls_internal_md2_process( ctx->md_ctx ) );
+#endif
+#if defined(MBEDTLS_MD4_C)
+ case MBEDTLS_MD_MD4:
+ return( mbedtls_internal_md4_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_MD5_C)
+ case MBEDTLS_MD_MD5:
+ return( mbedtls_internal_md5_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_RIPEMD160_C)
+ case MBEDTLS_MD_RIPEMD160:
+ return( mbedtls_internal_ripemd160_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA1_C)
+ case MBEDTLS_MD_SHA1:
+ return( mbedtls_internal_sha1_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_MD_SHA224:
+ case MBEDTLS_MD_SHA256:
+ return( mbedtls_internal_sha256_process( ctx->md_ctx, data ) );
+#endif
+#if defined(MBEDTLS_SHA512_C)
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_MD_SHA384:
+#endif
+ case MBEDTLS_MD_SHA512:
+ return( mbedtls_internal_sha512_process( ctx->md_ctx, data ) );
+#endif
+ default:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ }
}
unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info )
diff --git a/thirdparty/mbedtls/library/md2.c b/thirdparty/mbedtls/library/md2.c
index 58bd6d8f6b..7264e30313 100644
--- a/thirdparty/mbedtls/library/md2.c
+++ b/thirdparty/mbedtls/library/md2.c
@@ -2,13 +2,7 @@
* RFC 1115/1319 compliant MD2 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD2 algorithm was designed by Ron Rivest in 1989.
@@ -50,16 +23,13 @@
* http://www.ietf.org/rfc/rfc1319.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD2_C)
#include "mbedtls/md2.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -198,7 +168,7 @@ int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
while( ilen > 0 )
@@ -240,7 +210,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx,
int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
unsigned char x;
@@ -278,7 +248,7 @@ int mbedtls_md2_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md2_context ctx;
mbedtls_md2_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c
index 9a825327f4..eaa679a0a6 100644
--- a/thirdparty/mbedtls/library/md4.c
+++ b/thirdparty/mbedtls/library/md4.c
@@ -2,13 +2,7 @@
* RFC 1186/1320 compliant MD4 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD4 algorithm was designed by Ron Rivest in 1990.
@@ -50,16 +23,13 @@
* http://www.ietf.org/rfc/rfc1320.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD4_C)
#include "mbedtls/md4.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,29 +44,6 @@
#if !defined(MBEDTLS_MD4_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_md4_init( mbedtls_md4_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md4_context ) );
@@ -148,22 +95,22 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
uint32_t X[16], A, B, C, D;
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
@@ -284,7 +231,7 @@ int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -354,7 +301,7 @@ static const unsigned char md4_padding[64] =
int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@@ -363,8 +310,8 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
+ MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
+ MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -377,10 +324,10 @@ int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
return( ret );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
}
@@ -402,7 +349,7 @@ int mbedtls_md4_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md4_context ctx;
mbedtls_md4_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c
index a2e1ca77ad..4b53fcf367 100644
--- a/thirdparty/mbedtls/library/md5.c
+++ b/thirdparty/mbedtls/library/md5.c
@@ -2,13 +2,7 @@
* RFC 1321 compliant MD5 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The MD5 algorithm was designed by Ron Rivest in 1991.
@@ -49,16 +22,13 @@
* http://www.ietf.org/rfc/rfc1321.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MD5_C)
#include "mbedtls/md5.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -73,29 +43,6 @@
#if !defined(MBEDTLS_MD5_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_md5_init( mbedtls_md5_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_md5_context ) );
@@ -147,22 +94,22 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
uint32_t X[16], A, B, C, D;
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
#define S(x,n) \
( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) )
@@ -290,7 +237,7 @@ int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -349,7 +296,7 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx,
int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -383,8 +330,8 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, ctx->buffer, 56 );
- PUT_UINT32_LE( high, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_LE( low, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_LE( high, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -392,10 +339,10 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
return( 0 );
}
@@ -417,7 +364,7 @@ int mbedtls_md5_ret( const unsigned char *input,
size_t ilen,
unsigned char output[16] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md5_context ctx;
mbedtls_md5_init( &ctx );
diff --git a/thirdparty/mbedtls/library/md_wrap.c b/thirdparty/mbedtls/library/md_wrap.c
deleted file mode 100644
index 7459db2faf..0000000000
--- a/thirdparty/mbedtls/library/md_wrap.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/**
- * \file md_wrap.c
- *
- * \brief Generic message digest wrapper for mbed TLS
- *
- * \author Adriaan de Jong <dejong@fox-it.com>
- *
- * 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- */
-
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
-#if defined(MBEDTLS_MD_C)
-
-#include "mbedtls/md_internal.h"
-
-#if defined(MBEDTLS_MD2_C)
-#include "mbedtls/md2.h"
-#endif
-
-#if defined(MBEDTLS_MD4_C)
-#include "mbedtls/md4.h"
-#endif
-
-#if defined(MBEDTLS_MD5_C)
-#include "mbedtls/md5.h"
-#endif
-
-#if defined(MBEDTLS_RIPEMD160_C)
-#include "mbedtls/ripemd160.h"
-#endif
-
-#if defined(MBEDTLS_SHA1_C)
-#include "mbedtls/sha1.h"
-#endif
-
-#if defined(MBEDTLS_SHA256_C)
-#include "mbedtls/sha256.h"
-#endif
-
-#if defined(MBEDTLS_SHA512_C)
-#include "mbedtls/sha512.h"
-#endif
-
-#if defined(MBEDTLS_PLATFORM_C)
-#include "mbedtls/platform.h"
-#else
-#include <stdlib.h>
-#define mbedtls_calloc calloc
-#define mbedtls_free free
-#endif
-
-#if defined(MBEDTLS_MD2_C)
-
-static int md2_starts_wrap( void *ctx )
-{
- return( mbedtls_md2_starts_ret( (mbedtls_md2_context *) ctx ) );
-}
-
-static int md2_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md2_update_ret( (mbedtls_md2_context *) ctx, input, ilen ) );
-}
-
-static int md2_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md2_finish_ret( (mbedtls_md2_context *) ctx, output ) );
-}
-
-static void *md2_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) );
-
- if( ctx != NULL )
- mbedtls_md2_init( (mbedtls_md2_context *) ctx );
-
- return( ctx );
-}
-
-static void md2_ctx_free( void *ctx )
-{
- mbedtls_md2_free( (mbedtls_md2_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md2_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md2_clone( (mbedtls_md2_context *) dst,
- (const mbedtls_md2_context *) src );
-}
-
-static int md2_process_wrap( void *ctx, const unsigned char *data )
-{
- ((void) data);
-
- return( mbedtls_internal_md2_process( (mbedtls_md2_context *) ctx ) );
-}
-
-const mbedtls_md_info_t mbedtls_md2_info = {
- MBEDTLS_MD_MD2,
- "MD2",
- 16,
- 16,
- md2_starts_wrap,
- md2_update_wrap,
- md2_finish_wrap,
- mbedtls_md2_ret,
- md2_ctx_alloc,
- md2_ctx_free,
- md2_clone_wrap,
- md2_process_wrap,
-};
-
-#endif /* MBEDTLS_MD2_C */
-
-#if defined(MBEDTLS_MD4_C)
-
-static int md4_starts_wrap( void *ctx )
-{
- return( mbedtls_md4_starts_ret( (mbedtls_md4_context *) ctx ) );
-}
-
-static int md4_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md4_update_ret( (mbedtls_md4_context *) ctx, input, ilen ) );
-}
-
-static int md4_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md4_finish_ret( (mbedtls_md4_context *) ctx, output ) );
-}
-
-static void *md4_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) );
-
- if( ctx != NULL )
- mbedtls_md4_init( (mbedtls_md4_context *) ctx );
-
- return( ctx );
-}
-
-static void md4_ctx_free( void *ctx )
-{
- mbedtls_md4_free( (mbedtls_md4_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md4_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md4_clone( (mbedtls_md4_context *) dst,
- (const mbedtls_md4_context *) src );
-}
-
-static int md4_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md4_process( (mbedtls_md4_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md4_info = {
- MBEDTLS_MD_MD4,
- "MD4",
- 16,
- 64,
- md4_starts_wrap,
- md4_update_wrap,
- md4_finish_wrap,
- mbedtls_md4_ret,
- md4_ctx_alloc,
- md4_ctx_free,
- md4_clone_wrap,
- md4_process_wrap,
-};
-
-#endif /* MBEDTLS_MD4_C */
-
-#if defined(MBEDTLS_MD5_C)
-
-static int md5_starts_wrap( void *ctx )
-{
- return( mbedtls_md5_starts_ret( (mbedtls_md5_context *) ctx ) );
-}
-
-static int md5_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_md5_update_ret( (mbedtls_md5_context *) ctx, input, ilen ) );
-}
-
-static int md5_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_md5_finish_ret( (mbedtls_md5_context *) ctx, output ) );
-}
-
-static void *md5_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) );
-
- if( ctx != NULL )
- mbedtls_md5_init( (mbedtls_md5_context *) ctx );
-
- return( ctx );
-}
-
-static void md5_ctx_free( void *ctx )
-{
- mbedtls_md5_free( (mbedtls_md5_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void md5_clone_wrap( void *dst, const void *src )
-{
- mbedtls_md5_clone( (mbedtls_md5_context *) dst,
- (const mbedtls_md5_context *) src );
-}
-
-static int md5_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_md5_process( (mbedtls_md5_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_md5_info = {
- MBEDTLS_MD_MD5,
- "MD5",
- 16,
- 64,
- md5_starts_wrap,
- md5_update_wrap,
- md5_finish_wrap,
- mbedtls_md5_ret,
- md5_ctx_alloc,
- md5_ctx_free,
- md5_clone_wrap,
- md5_process_wrap,
-};
-
-#endif /* MBEDTLS_MD5_C */
-
-#if defined(MBEDTLS_RIPEMD160_C)
-
-static int ripemd160_starts_wrap( void *ctx )
-{
- return( mbedtls_ripemd160_starts_ret( (mbedtls_ripemd160_context *) ctx ) );
-}
-
-static int ripemd160_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_ripemd160_update_ret( (mbedtls_ripemd160_context *) ctx,
- input, ilen ) );
-}
-
-static int ripemd160_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_ripemd160_finish_ret( (mbedtls_ripemd160_context *) ctx,
- output ) );
-}
-
-static void *ripemd160_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) );
-
- if( ctx != NULL )
- mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx );
-
- return( ctx );
-}
-
-static void ripemd160_ctx_free( void *ctx )
-{
- mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void ripemd160_clone_wrap( void *dst, const void *src )
-{
- mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst,
- (const mbedtls_ripemd160_context *) src );
-}
-
-static int ripemd160_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_ripemd160_process(
- (mbedtls_ripemd160_context *) ctx, data ) );
-}
-
-const mbedtls_md_info_t mbedtls_ripemd160_info = {
- MBEDTLS_MD_RIPEMD160,
- "RIPEMD160",
- 20,
- 64,
- ripemd160_starts_wrap,
- ripemd160_update_wrap,
- ripemd160_finish_wrap,
- mbedtls_ripemd160_ret,
- ripemd160_ctx_alloc,
- ripemd160_ctx_free,
- ripemd160_clone_wrap,
- ripemd160_process_wrap,
-};
-
-#endif /* MBEDTLS_RIPEMD160_C */
-
-#if defined(MBEDTLS_SHA1_C)
-
-static int sha1_starts_wrap( void *ctx )
-{
- return( mbedtls_sha1_starts_ret( (mbedtls_sha1_context *) ctx ) );
-}
-
-static int sha1_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha1_update_ret( (mbedtls_sha1_context *) ctx,
- input, ilen ) );
-}
-
-static int sha1_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha1_finish_ret( (mbedtls_sha1_context *) ctx, output ) );
-}
-
-static void *sha1_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) );
-
- if( ctx != NULL )
- mbedtls_sha1_init( (mbedtls_sha1_context *) ctx );
-
- return( ctx );
-}
-
-static void sha1_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha1_clone( (mbedtls_sha1_context *) dst,
- (const mbedtls_sha1_context *) src );
-}
-
-static void sha1_ctx_free( void *ctx )
-{
- mbedtls_sha1_free( (mbedtls_sha1_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static int sha1_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha1_process( (mbedtls_sha1_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha1_info = {
- MBEDTLS_MD_SHA1,
- "SHA1",
- 20,
- 64,
- sha1_starts_wrap,
- sha1_update_wrap,
- sha1_finish_wrap,
- mbedtls_sha1_ret,
- sha1_ctx_alloc,
- sha1_ctx_free,
- sha1_clone_wrap,
- sha1_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA1_C */
-
-/*
- * Wrappers for generic message digests
- */
-#if defined(MBEDTLS_SHA256_C)
-
-static int sha224_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 1 ) );
-}
-
-static int sha224_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha256_update_ret( (mbedtls_sha256_context *) ctx,
- input, ilen ) );
-}
-
-static int sha224_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha256_finish_ret( (mbedtls_sha256_context *) ctx,
- output ) );
-}
-
-static int sha224_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha224_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) );
-
- if( ctx != NULL )
- mbedtls_sha256_init( (mbedtls_sha256_context *) ctx );
-
- return( ctx );
-}
-
-static void sha224_ctx_free( void *ctx )
-{
- mbedtls_sha256_free( (mbedtls_sha256_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha224_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha256_clone( (mbedtls_sha256_context *) dst,
- (const mbedtls_sha256_context *) src );
-}
-
-static int sha224_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha256_process( (mbedtls_sha256_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha224_info = {
- MBEDTLS_MD_SHA224,
- "SHA224",
- 28,
- 64,
- sha224_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha224_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-static int sha256_starts_wrap( void *ctx )
-{
- return( mbedtls_sha256_starts_ret( (mbedtls_sha256_context *) ctx, 0 ) );
-}
-
-static int sha256_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha256_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha256_info = {
- MBEDTLS_MD_SHA256,
- "SHA256",
- 32,
- 64,
- sha256_starts_wrap,
- sha224_update_wrap,
- sha224_finish_wrap,
- sha256_wrap,
- sha224_ctx_alloc,
- sha224_ctx_free,
- sha224_clone_wrap,
- sha224_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA256_C */
-
-#if defined(MBEDTLS_SHA512_C)
-
-static int sha384_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 1 ) );
-}
-
-static int sha384_update_wrap( void *ctx, const unsigned char *input,
- size_t ilen )
-{
- return( mbedtls_sha512_update_ret( (mbedtls_sha512_context *) ctx,
- input, ilen ) );
-}
-
-static int sha384_finish_wrap( void *ctx, unsigned char *output )
-{
- return( mbedtls_sha512_finish_ret( (mbedtls_sha512_context *) ctx,
- output ) );
-}
-
-static int sha384_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 1 ) );
-}
-
-static void *sha384_ctx_alloc( void )
-{
- void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) );
-
- if( ctx != NULL )
- mbedtls_sha512_init( (mbedtls_sha512_context *) ctx );
-
- return( ctx );
-}
-
-static void sha384_ctx_free( void *ctx )
-{
- mbedtls_sha512_free( (mbedtls_sha512_context *) ctx );
- mbedtls_free( ctx );
-}
-
-static void sha384_clone_wrap( void *dst, const void *src )
-{
- mbedtls_sha512_clone( (mbedtls_sha512_context *) dst,
- (const mbedtls_sha512_context *) src );
-}
-
-static int sha384_process_wrap( void *ctx, const unsigned char *data )
-{
- return( mbedtls_internal_sha512_process( (mbedtls_sha512_context *) ctx,
- data ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha384_info = {
- MBEDTLS_MD_SHA384,
- "SHA384",
- 48,
- 128,
- sha384_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha384_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-static int sha512_starts_wrap( void *ctx )
-{
- return( mbedtls_sha512_starts_ret( (mbedtls_sha512_context *) ctx, 0 ) );
-}
-
-static int sha512_wrap( const unsigned char *input, size_t ilen,
- unsigned char *output )
-{
- return( mbedtls_sha512_ret( input, ilen, output, 0 ) );
-}
-
-const mbedtls_md_info_t mbedtls_sha512_info = {
- MBEDTLS_MD_SHA512,
- "SHA512",
- 64,
- 128,
- sha512_starts_wrap,
- sha384_update_wrap,
- sha384_finish_wrap,
- sha512_wrap,
- sha384_ctx_alloc,
- sha384_ctx_free,
- sha384_clone_wrap,
- sha384_process_wrap,
-};
-
-#endif /* MBEDTLS_SHA512_C */
-
-#endif /* MBEDTLS_MD_C */
diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c
index 915ec3ae9d..0d5d27d3de 100644
--- a/thirdparty/mbedtls/library/memory_buffer_alloc.c
+++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c
@@ -2,13 +2,7 @@
* Buffer-based memory allocator
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
#include "mbedtls/memory_buffer_alloc.h"
diff --git a/thirdparty/mbedtls/library/mps_common.h b/thirdparty/mbedtls/library/mps_common.h
new file mode 100644
index 0000000000..d20776f159
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_common.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_common.h
+ *
+ * \brief Common functions and macros used by MPS
+ */
+
+#ifndef MBEDTLS_MPS_COMMON_H
+#define MBEDTLS_MPS_COMMON_H
+
+#include "mps_error.h"
+
+#include <stdio.h>
+
+/**
+ * \name SECTION: MPS Configuration
+ *
+ * \{
+ */
+
+/*! This flag controls whether the MPS-internal components
+ * (reader, writer, Layer 1-3) perform validation of the
+ * expected abstract state at the entry of API calls.
+ *
+ * Context: All MPS API functions impose assumptions/preconditions on the
+ * context on which they operate. For example, every structure has a notion of
+ * state integrity which is established by `xxx_init()` and preserved by any
+ * calls to the MPS API which satisfy their preconditions and either succeed,
+ * or fail with an error code which is explicitly documented to not corrupt
+ * structure integrity (such as WANT_READ and WANT_WRITE);
+ * apart from `xxx_init()` any function assumes state integrity as a
+ * precondition (but usually more). If any of the preconditions is violated,
+ * the function's behavior is entirely undefined.
+ * In addition to state integrity, all MPS structures have a more refined
+ * notion of abstract state that the API operates on. For example, all layers
+ * have a notion of 'abtract read state' which indicates if incoming data has
+ * been passed to the user, e.g. through mps_l2_read_start() for Layer 2
+ * or mps_l3_read() in Layer 3. After such a call, it doesn't make sense to
+ * call these reading functions again until the incoming data has been
+ * explicitly 'consumed', e.g. through mps_l2_read_consume() for Layer 2 or
+ * mps_l3_read_consume() on Layer 3. However, even if it doesn't make sense,
+ * it's a design choice whether the API should fail gracefully on such
+ * non-sensical calls or not, and that's what this option is about:
+ *
+ * This option determines whether the expected abstract state
+ * is part of the API preconditions or not: If the option is set,
+ * then the abstract state is not part of the precondition and is
+ * thus required to be validated by the implementation. If an unexpected
+ * abstract state is encountered, the implementation must fail gracefully
+ * with error #MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED.
+ * Conversely, if this option is not set, then the expected abstract state
+ * is included in the preconditions of the respective API calls, and
+ * an implementation's behaviour is undefined if the abstract state is
+ * not as expected.
+ *
+ * For example: Enabling this makes mps_l2_read_done() fail if
+ * no incoming record is currently open; disabling this would
+ * lead to undefined behavior in this case.
+ *
+ * Comment this to remove state validation.
+ */
+#define MBEDTLS_MPS_STATE_VALIDATION
+
+/*! This flag enables/disables assertions on the internal state of MPS.
+ *
+ * Assertions are sanity checks that should never trigger when MPS
+ * is used within the bounds of its API and preconditions.
+ *
+ * Enabling this increases security by limiting the scope of
+ * potential bugs, but comes at the cost of increased code size.
+ *
+ * Note: So far, there is no guiding principle as to what
+ * expected conditions merit an assertion, and which don't.
+ *
+ * Comment this to disable assertions.
+ */
+#define MBEDTLS_MPS_ENABLE_ASSERTIONS
+
+/*! This flag controls whether tracing for MPS should be enabled. */
+//#define MBEDTLS_MPS_ENABLE_TRACE
+
+#if defined(MBEDTLS_MPS_STATE_VALIDATION)
+
+#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \
+ do \
+ { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR, string ); \
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED ); \
+ } \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_STATE_VALIDATION */
+
+#define MBEDTLS_MPS_STATE_VALIDATE_RAW( cond, string ) \
+ do \
+ { \
+ ( cond ); \
+ } while( 0 )
+
+#endif /* MBEDTLS_MPS_STATE_VALIDATION */
+
+#if defined(MBEDTLS_MPS_ENABLE_ASSERTIONS)
+
+#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) \
+ do \
+ { \
+ if( !(cond) ) \
+ { \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR, string ); \
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_INTERNAL_ERROR ); \
+ } \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
+
+#define MBEDTLS_MPS_ASSERT_RAW( cond, string ) do {} while( 0 )
+
+#endif /* MBEDTLS_MPS_ENABLE_ASSERTIONS */
+
+
+/* \} name SECTION: MPS Configuration */
+
+/**
+ * \name SECTION: Common types
+ *
+ * Various common types used throughout MPS.
+ * \{
+ */
+
+/** \brief The type of buffer sizes and offsets used in MPS structures.
+ *
+ * This is an unsigned integer type that should be large enough to
+ * hold the length of any buffer or message processed by MPS.
+ *
+ * The reason to pick a value as small as possible here is
+ * to reduce the size of MPS structures.
+ *
+ * \warning Care has to be taken when using a narrower type
+ * than ::mbedtls_mps_size_t here because of
+ * potential truncation during conversion.
+ *
+ * \warning Handshake messages in TLS may be up to 2^24 ~ 16Mb in size.
+ * If mbedtls_mps_[opt_]stored_size_t is smaller than that, the
+ * maximum handshake message is restricted accordingly.
+ *
+ * For now, we use the default type of size_t throughout, and the use of
+ * smaller types or different types for ::mbedtls_mps_size_t and
+ * ::mbedtls_mps_stored_size_t is not yet supported.
+ *
+ */
+typedef size_t mbedtls_mps_stored_size_t;
+#define MBEDTLS_MPS_STORED_SIZE_MAX ( (mbedtls_mps_stored_size_t) -1 )
+
+/** \brief The type of buffer sizes and offsets used in the MPS API
+ * and implementation.
+ *
+ * This must be at least as wide as ::mbedtls_stored_size_t but
+ * may be chosen to be strictly larger if more suitable for the
+ * target architecture.
+ *
+ * For example, in a test build for ARM Thumb, using uint_fast16_t
+ * instead of uint16_t reduced the code size from 1060 Byte to 962 Byte,
+ * so almost 10%.
+ */
+typedef size_t mbedtls_mps_size_t;
+#define MBEDTLS_MPS_SIZE_MAX ( (mbedtls_mps_size_t) -1 )
+
+#if MBEDTLS_MPS_STORED_SIZE_MAX > MBEDTLS_MPS_SIZE_MAX
+#error "Misconfiguration of mbedtls_mps_size_t and mbedtls_mps_stored_size_t."
+#endif
+
+/* \} SECTION: Common types */
+
+
+#endif /* MBEDTLS_MPS_COMMON_H */
diff --git a/thirdparty/mbedtls/library/mps_error.h b/thirdparty/mbedtls/library/mps_error.h
new file mode 100644
index 0000000000..f78d9a05f1
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_error.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_error.h
+ *
+ * \brief Error codes used by MPS
+ */
+
+#ifndef MBEDTLS_MPS_ERROR_H
+#define MBEDTLS_MPS_ERROR_H
+
+
+/* TODO: The error code allocation needs to be revisited:
+ *
+ * - Should we make (some of) the MPS Reader error codes public?
+ * If so, we need to adjust MBEDTLS_MPS_READER_MAKE_ERROR() to hit
+ * a gap in the Mbed TLS public error space.
+ * If not, we have to make sure we don't forward those errors
+ * at the level of the public API -- no risk at the moment as
+ * long as MPS is an experimental component not accessible from
+ * public API.
+ */
+
+/**
+ * \name SECTION: MPS general error codes
+ *
+ * \{
+ */
+
+#ifndef MBEDTLS_MPS_ERR_BASE
+#define MBEDTLS_MPS_ERR_BASE ( 0 )
+#endif
+
+#define MBEDTLS_MPS_MAKE_ERROR(code) \
+ ( -( MBEDTLS_MPS_ERR_BASE | (code) ) )
+
+#define MBEDTLS_ERR_MPS_OPERATION_UNEXPECTED MBEDTLS_MPS_MAKE_ERROR( 0x1 )
+#define MBEDTLS_ERR_MPS_INTERNAL_ERROR MBEDTLS_MPS_MAKE_ERROR( 0x2 )
+
+/* \} name SECTION: MPS general error codes */
+
+/**
+ * \name SECTION: MPS Reader error codes
+ *
+ * \{
+ */
+
+#ifndef MBEDTLS_MPS_READER_ERR_BASE
+#define MBEDTLS_MPS_READER_ERR_BASE ( 1 << 8 )
+#endif
+
+#define MBEDTLS_MPS_READER_MAKE_ERROR(code) \
+ ( -( MBEDTLS_MPS_READER_ERR_BASE | (code) ) )
+
+/*! An attempt to reclaim the data buffer from a reader failed because
+ * the user hasn't yet read and committed all of it. */
+#define MBEDTLS_ERR_MPS_READER_DATA_LEFT MBEDTLS_MPS_READER_MAKE_ERROR( 0x1 )
+
+/*! An invalid argument was passed to the reader. */
+#define MBEDTLS_ERR_MPS_READER_INVALID_ARG MBEDTLS_MPS_READER_MAKE_ERROR( 0x2 )
+
+/*! An attempt to move a reader to consuming mode through mbedtls_mps_reader_feed()
+ * after pausing failed because the provided data is not sufficient to serve the
+ * read requests that led to the pausing. */
+#define MBEDTLS_ERR_MPS_READER_NEED_MORE MBEDTLS_MPS_READER_MAKE_ERROR( 0x3 )
+
+/*! A get request failed because not enough data is available in the reader. */
+#define MBEDTLS_ERR_MPS_READER_OUT_OF_DATA MBEDTLS_MPS_READER_MAKE_ERROR( 0x4 )
+
+/*!< A get request after pausing and reactivating the reader failed because
+ * the request is not in line with the request made prior to pausing. The user
+ * must not change it's 'strategy' after pausing and reactivating a reader. */
+#define MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS MBEDTLS_MPS_READER_MAKE_ERROR( 0x5 )
+
+/*! An attempt to reclaim the data buffer from a reader failed because the reader
+ * has no accumulator it can use to backup the data that hasn't been processed. */
+#define MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR MBEDTLS_MPS_READER_MAKE_ERROR( 0x6 )
+
+/*! An attempt to reclaim the data buffer from a reader failed because the
+ * accumulator passed to the reader is not large enough to hold both the
+ * data that hasn't been processed and the excess of the last read-request. */
+#define MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL MBEDTLS_MPS_READER_MAKE_ERROR( 0x7 )
+
+/* \} name SECTION: MPS Reader error codes */
+
+#endif /* MBEDTLS_MPS_ERROR_H */
diff --git a/thirdparty/mbedtls/library/mps_reader.c b/thirdparty/mbedtls/library/mps_reader.c
new file mode 100644
index 0000000000..9af5073cc9
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_reader.c
@@ -0,0 +1,564 @@
+/*
+ * Message Processing Stack, Reader implementation
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mps_reader.h"
+#include "mps_common.h"
+#include "mps_trace.h"
+
+#include <string.h>
+
+#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
+ !defined(inline) && !defined(__cplusplus)
+#define inline __inline
+#endif
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+static int mbedtls_mps_trace_id = MBEDTLS_MPS_TRACE_BIT_READER;
+#endif /* MBEDTLS_MPS_ENABLE_TRACE */
+
+/*
+ * GENERAL NOTE ON CODING STYLE
+ *
+ * The following code intentionally separates memory loads
+ * and stores from other operations (arithmetic or branches).
+ * This leads to the introduction of many local variables
+ * and significantly increases the C-code line count, but
+ * should not increase the size of generated assembly.
+ *
+ * The reason for this is twofold:
+ * (1) It will ease verification efforts using the VST
+ * (Verified Software Toolchain)
+ * whose program logic cannot directly reason
+ * about instructions containing a load or store in
+ * addition to other operations (e.g. *p = *q or
+ * tmp = *p + 42).
+ * (2) Operating on local variables and writing the results
+ * back to the target contexts on success only
+ * allows to maintain structure invariants even
+ * on failure - this in turn has two benefits:
+ * (2.a) If for some reason an error code is not caught
+ * and operation continues, functions are nonetheless
+ * called with sane contexts, reducing the risk
+ * of dangerous behavior.
+ * (2.b) Randomized testing is easier if structures
+ * remain intact even in the face of failing
+ * and/or non-sensical calls.
+ * Moreover, it might even reduce code-size because
+ * the compiler need not write back temporary results
+ * to memory in case of failure.
+ *
+ */
+
+static inline int mps_reader_is_accumulating(
+ mbedtls_mps_reader const *rd )
+{
+ mbedtls_mps_size_t acc_remaining;
+ if( rd->acc == NULL )
+ return( 0 );
+
+ acc_remaining = rd->acc_share.acc_remaining;
+ return( acc_remaining > 0 );
+}
+
+static inline int mps_reader_is_producing(
+ mbedtls_mps_reader const *rd )
+{
+ unsigned char *frag = rd->frag;
+ return( frag == NULL );
+}
+
+static inline int mps_reader_is_consuming(
+ mbedtls_mps_reader const *rd )
+{
+ return( !mps_reader_is_producing( rd ) );
+}
+
+static inline mbedtls_mps_size_t mps_reader_get_fragment_offset(
+ mbedtls_mps_reader const *rd )
+{
+ unsigned char *acc = rd->acc;
+ mbedtls_mps_size_t frag_offset;
+
+ if( acc == NULL )
+ return( 0 );
+
+ frag_offset = rd->acc_share.frag_offset;
+ return( frag_offset );
+}
+
+static inline mbedtls_mps_size_t mps_reader_serving_from_accumulator(
+ mbedtls_mps_reader const *rd )
+{
+ mbedtls_mps_size_t frag_offset, end;
+
+ frag_offset = mps_reader_get_fragment_offset( rd );
+ end = rd->end;
+
+ return( end < frag_offset );
+}
+
+static inline void mps_reader_zero( mbedtls_mps_reader *rd )
+{
+ /* A plain memset() would likely be more efficient,
+ * but the current way of zeroing makes it harder
+ * to overlook fields which should not be zero-initialized.
+ * It's also more suitable for FV efforts since it
+ * doesn't require reasoning about structs being
+ * interpreted as unstructured binary blobs. */
+ static mbedtls_mps_reader const zero =
+ { .frag = NULL,
+ .frag_len = 0,
+ .commit = 0,
+ .end = 0,
+ .pending = 0,
+ .acc = NULL,
+ .acc_len = 0,
+ .acc_available = 0,
+ .acc_share = { .acc_remaining = 0 }
+ };
+ *rd = zero;
+}
+
+int mbedtls_mps_reader_init( mbedtls_mps_reader *rd,
+ unsigned char *acc,
+ mbedtls_mps_size_t acc_len )
+{
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_init" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Accumulator size: %u bytes", (unsigned) acc_len );
+ mps_reader_zero( rd );
+ rd->acc = acc;
+ rd->acc_len = acc_len;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_free( mbedtls_mps_reader *rd )
+{
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_free" );
+ mps_reader_zero( rd );
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_feed( mbedtls_mps_reader *rd,
+ unsigned char *new_frag,
+ mbedtls_mps_size_t new_frag_len )
+{
+ mbedtls_mps_size_t copy_to_acc;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_feed" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Fragment length: %u bytes", (unsigned) new_frag_len );
+
+ if( new_frag == NULL )
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_INVALID_ARG );
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_producing( rd ),
+ "mbedtls_mps_reader_feed() requires reader to be in producing mode" );
+
+ if( mps_reader_is_accumulating( rd ) )
+ {
+ unsigned char *acc = rd->acc;
+ mbedtls_mps_size_t acc_remaining = rd->acc_share.acc_remaining;
+ mbedtls_mps_size_t acc_available = rd->acc_available;
+
+ /* Skip over parts of the accumulator that have already been filled. */
+ acc += acc_available;
+
+ copy_to_acc = acc_remaining;
+ if( copy_to_acc > new_frag_len )
+ copy_to_acc = new_frag_len;
+
+ /* Copy new contents to accumulator. */
+ memcpy( acc, new_frag, copy_to_acc );
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Copy new data of size %u of %u into accumulator at offset %u",
+ (unsigned) copy_to_acc, (unsigned) new_frag_len, (unsigned) acc_available );
+
+ /* Check if, with the new fragment, we have enough data. */
+ acc_remaining -= copy_to_acc;
+ if( acc_remaining > 0 )
+ {
+ /* We need to accumulate more data. Stay in producing mode. */
+ acc_available += copy_to_acc;
+ rd->acc_share.acc_remaining = acc_remaining;
+ rd->acc_available = acc_available;
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_NEED_MORE );
+ }
+
+ /* We have filled the accumulator: Move to consuming mode. */
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Enough data available to serve user request" );
+
+ /* Remember overlap of accumulator and fragment. */
+ rd->acc_share.frag_offset = acc_available;
+ acc_available += copy_to_acc;
+ rd->acc_available = acc_available;
+ }
+ else /* Not accumulating */
+ {
+ rd->acc_share.frag_offset = 0;
+ }
+
+ rd->frag = new_frag;
+ rd->frag_len = new_frag_len;
+ rd->commit = 0;
+ rd->end = 0;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+
+int mbedtls_mps_reader_get( mbedtls_mps_reader *rd,
+ mbedtls_mps_size_t desired,
+ unsigned char **buffer,
+ mbedtls_mps_size_t *buflen )
+{
+ unsigned char *frag;
+ mbedtls_mps_size_t frag_len, frag_offset, end, frag_fetched, frag_remaining;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_get" );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "* Bytes requested: %u", (unsigned) desired );
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_get() requires reader to be in consuming mode" );
+
+ end = rd->end;
+ frag_offset = mps_reader_get_fragment_offset( rd );
+
+ /* Check if we're still serving from the accumulator. */
+ if( mps_reader_serving_from_accumulator( rd ) )
+ {
+ /* Illustration of supported and unsupported cases:
+ *
+ * - Allowed #1
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +-----v-------v-------------+
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * - Allowed #2
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +----------v----------------v
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * - Not allowed #1 (could be served, but we don't actually use it):
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end+desired
+ * | |
+ * +------v-------------v------+
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ *
+ * - Not allowed #2 (can't be served with a contiguous buffer):
+ *
+ * +-----------------------------------+
+ * | frag |
+ * +-----------------------------------+
+ *
+ * end end + desired
+ * | |
+ * +------v--------------------+ v
+ * | acc |
+ * +---------------------------+
+ * | |
+ * frag_offset acc_available
+ *
+ * In case of Allowed #2 we're switching to serve from
+ * `frag` starting from the next call to mbedtls_mps_reader_get().
+ */
+
+ unsigned char *acc;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Serve the request from the accumulator" );
+ if( frag_offset - end < desired )
+ {
+ mbedtls_mps_size_t acc_available;
+ acc_available = rd->acc_available;
+ if( acc_available - end != desired )
+ {
+ /* It might be possible to serve some of these situations by
+ * making additional space in the accumulator, removing those
+ * parts that have already been committed.
+ * On the other hand, this brings additional complexity and
+ * enlarges the code size, while there doesn't seem to be a use
+ * case where we don't attempt exactly the same `get` calls when
+ * resuming on a reader than what we tried before pausing it.
+ * If we believe we adhere to this restricted usage throughout
+ * the library, this check is a good opportunity to
+ * validate this. */
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_INCONSISTENT_REQUESTS );
+ }
+ }
+
+ acc = rd->acc;
+ acc += end;
+
+ *buffer = acc;
+ if( buflen != NULL )
+ *buflen = desired;
+
+ end += desired;
+ rd->end = end;
+ rd->pending = 0;
+
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+ }
+
+ /* Attempt to serve the request from the current fragment */
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Serve the request from the current fragment." );
+
+ frag_len = rd->frag_len;
+ frag_fetched = end - frag_offset; /* The amount of data from the current
+ * fragment that has already been passed
+ * to the user. */
+ frag_remaining = frag_len - frag_fetched; /* Remaining data in fragment */
+
+ /* Check if we can serve the read request from the fragment. */
+ if( frag_remaining < desired )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There's not enough data in the current fragment "
+ "to serve the request." );
+ /* There's not enough data in the current fragment,
+ * so either just RETURN what we have or fail. */
+ if( buflen == NULL )
+ {
+ if( frag_remaining > 0 )
+ {
+ rd->pending = desired - frag_remaining;
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Remember to collect %u bytes before re-opening",
+ (unsigned) rd->pending );
+ }
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_OUT_OF_DATA );
+ }
+
+ desired = frag_remaining;
+ }
+
+ /* There's enough data in the current fragment to serve the
+ * (potentially modified) read request. */
+
+ frag = rd->frag;
+ frag += frag_fetched;
+
+ *buffer = frag;
+ if( buflen != NULL )
+ *buflen = desired;
+
+ end += desired;
+ rd->end = end;
+ rd->pending = 0;
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_commit( mbedtls_mps_reader *rd )
+{
+ mbedtls_mps_size_t end;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_commit" );
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_commit() requires reader to be in consuming mode" );
+
+ end = rd->end;
+ rd->commit = end;
+
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *rd,
+ int *paused )
+{
+ unsigned char *frag, *acc;
+ mbedtls_mps_size_t pending, commit;
+ mbedtls_mps_size_t acc_len, frag_offset, frag_len;
+ MBEDTLS_MPS_TRACE_INIT( "mbedtls_mps_reader_reclaim" );
+
+ if( paused != NULL )
+ *paused = 0;
+
+ MBEDTLS_MPS_STATE_VALIDATE_RAW( mps_reader_is_consuming( rd ),
+ "mbedtls_mps_reader_reclaim() requires reader to be in consuming mode" );
+
+ frag = rd->frag;
+ acc = rd->acc;
+ pending = rd->pending;
+ commit = rd->commit;
+ frag_len = rd->frag_len;
+
+ frag_offset = mps_reader_get_fragment_offset( rd );
+
+ if( pending == 0 )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "No unsatisfied read-request has been logged." );
+
+ /* Check if there's data left to be consumed. */
+ if( commit < frag_offset || commit - frag_offset < frag_len )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There is data left to be consumed." );
+ rd->end = commit;
+ MBEDTLS_MPS_TRACE_RETURN( MBEDTLS_ERR_MPS_READER_DATA_LEFT );
+ }
+
+ rd->acc_available = 0;
+ rd->acc_share.acc_remaining = 0;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Fragment has been fully processed and committed." );
+ }
+ else
+ {
+ int overflow;
+
+ mbedtls_mps_size_t acc_backup_offset;
+ mbedtls_mps_size_t acc_backup_len;
+ mbedtls_mps_size_t frag_backup_offset;
+ mbedtls_mps_size_t frag_backup_len;
+
+ mbedtls_mps_size_t backup_len;
+ mbedtls_mps_size_t acc_len_needed;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "There has been an unsatisfied read with %u bytes overhead.",
+ (unsigned) pending );
+
+ if( acc == NULL )
+ {
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "No accumulator present" );
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_NEED_ACCUMULATOR );
+ }
+ acc_len = rd->acc_len;
+
+ /* Check if the upper layer has already fetched
+ * and committed the contents of the accumulator. */
+ if( commit < frag_offset )
+ {
+ /* No, accumulator is still being processed. */
+ frag_backup_offset = 0;
+ frag_backup_len = frag_len;
+ acc_backup_offset = commit;
+ acc_backup_len = frag_offset - commit;
+ }
+ else
+ {
+ /* Yes, the accumulator is already processed. */
+ frag_backup_offset = commit - frag_offset;
+ frag_backup_len = frag_len - frag_backup_offset;
+ acc_backup_offset = 0;
+ acc_backup_len = 0;
+ }
+
+ backup_len = acc_backup_len + frag_backup_len;
+ acc_len_needed = backup_len + pending;
+
+ overflow = 0;
+ overflow |= ( backup_len < acc_backup_len );
+ overflow |= ( acc_len_needed < backup_len );
+
+ if( overflow || acc_len < acc_len_needed )
+ {
+ /* Except for the different return code, we behave as if
+ * there hadn't been a call to mbedtls_mps_reader_get()
+ * since the last commit. */
+ rd->end = commit;
+ rd->pending = 0;
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "The accumulator is too small to handle the backup." );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "* Size: %u", (unsigned) acc_len );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ "* Needed: %u (%u + %u)",
+ (unsigned) acc_len_needed,
+ (unsigned) backup_len, (unsigned) pending );
+ MBEDTLS_MPS_TRACE_RETURN(
+ MBEDTLS_ERR_MPS_READER_ACCUMULATOR_TOO_SMALL );
+ }
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Fragment backup: %u", (unsigned) frag_backup_len );
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Accumulator backup: %u", (unsigned) acc_backup_len );
+
+ /* Move uncommitted parts from the accumulator to the front
+ * of the accumulator. */
+ memmove( acc, acc + acc_backup_offset, acc_backup_len );
+
+ /* Copy uncmmitted parts of the current fragment to the
+ * accumulator. */
+ memcpy( acc + acc_backup_len,
+ frag + frag_backup_offset, frag_backup_len );
+
+ rd->acc_available = backup_len;
+ rd->acc_share.acc_remaining = pending;
+
+ if( paused != NULL )
+ *paused = 1;
+ }
+
+ rd->frag = NULL;
+ rd->frag_len = 0;
+
+ rd->commit = 0;
+ rd->end = 0;
+ rd->pending = 0;
+
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ "Final state: aa %u, al %u, ar %u",
+ (unsigned) rd->acc_available, (unsigned) rd->acc_len,
+ (unsigned) rd->acc_share.acc_remaining );
+ MBEDTLS_MPS_TRACE_RETURN( 0 );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/mps_reader.h b/thirdparty/mbedtls/library/mps_reader.h
new file mode 100644
index 0000000000..427c1bd254
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_reader.h
@@ -0,0 +1,382 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_reader.h
+ *
+ * \brief This file defines reader objects, which together with their
+ * sibling writer objects form the basis for the communication
+ * between the various layers of the Mbed TLS messaging stack,
+ * as well as the communication between the messaging stack and
+ * the (D)TLS handshake protocol implementation.
+ *
+ * Readers provide a means of transferring incoming data from
+ * a 'producer' providing it in chunks of arbitrary size, to
+ * a 'consumer' which fetches and processes it in chunks of
+ * again arbitrary, and potentially different, size.
+ *
+ * Readers can thus be seen as datagram-to-stream converters,
+ * and they abstract away the following two tasks from the user:
+ * 1. The pointer arithmetic of stepping through a producer-
+ * provided chunk in smaller chunks.
+ * 2. The merging of incoming data chunks in case the
+ * consumer requests data in larger chunks than what the
+ * producer provides.
+ *
+ * The basic abstract flow of operation is the following:
+ * - Initially, the reader is in 'producing mode'.
+ * - The producer hands an incoming data buffer to the reader,
+ * moving it from 'producing' to 'consuming' mode.
+ * - The consumer subsequently fetches and processes the buffer
+ * content. Once that's done -- or partially done and a consumer's
+ * request can't be fulfilled -- the producer revokes the reader's
+ * access to the incoming data buffer, putting the reader back to
+ * producing mode.
+ * - The producer subsequently gathers more incoming data and hands
+ * it to the reader until it switches back to consuming mode
+ * if enough data is available for the last consumer request to
+ * be satisfiable.
+ * - Repeat the above.
+ *
+ * The abstract states of the reader from the producer's and
+ * consumer's perspective are as follows:
+ *
+ * - From the perspective of the consumer, the state of the
+ * reader consists of the following:
+ * - A byte stream representing (concatenation of) the data
+ * received through calls to mbedtls_mps_reader_get(),
+ * - A marker within that byte stream indicating which data
+ * can be considered processed, and hence need not be retained,
+ * when the reader is passed back to the producer via
+ * mbedtls_mps_reader_reclaim().
+ * The marker is set via mbedtls_mps_reader_commit()
+ * which places it at the end of the current byte stream.
+ * The consumer need not be aware of the distinction between consumer
+ * and producer mode, because it only interfaces with the reader
+ * when the latter is in consuming mode.
+ *
+ * - From the perspective of the producer, the reader's state is one of:
+ * - Attached: The reader is in consuming mode.
+ * - Unset: No incoming data buffer is currently managed by the reader,
+ * and all previously handed incoming data buffers have been
+ * fully processed. More data needs to be fed into the reader
+ * via mbedtls_mps_reader_feed().
+ *
+ * - Accumulating: No incoming data buffer is currently managed by the
+ * reader, but some data from the previous incoming data
+ * buffer hasn't been processed yet and is internally
+ * held back.
+ * The Attached state belongs to consuming mode, while the Unset and
+ * Accumulating states belong to producing mode.
+ *
+ * Transitioning from the Unset or Accumulating state to Attached is
+ * done via successful calls to mbedtls_mps_reader_feed(), while
+ * transitioning from Attached to either Unset or Accumulating (depending
+ * on what has been processed) is done via mbedtls_mps_reader_reclaim().
+ *
+ * The following diagram depicts the producer-state progression:
+ *
+ * +------------------+ reclaim
+ * | Unset +<-------------------------------------+ get
+ * +--------|---------+ | +------+
+ * | | | |
+ * | | | |
+ * | feed +---------+---+--+ |
+ * +--------------------------------------> <---+
+ * | Attached |
+ * +--------------------------------------> <---+
+ * | feed, enough data available +---------+---+--+ |
+ * | to serve previous consumer request | | |
+ * | | | |
+ * +--------+---------+ | +------+
+ * +----> Accumulating |<-------------------------------------+ commit
+ * | +---+--------------+ reclaim, previous read request
+ * | | couldn't be fulfilled
+ * | |
+ * +--------+
+ * feed, need more data to serve
+ * previous consumer request
+ * |
+ * |
+ * producing mode | consuming mode
+ * |
+ *
+ */
+
+#ifndef MBEDTLS_READER_H
+#define MBEDTLS_READER_H
+
+#include <stdio.h>
+
+#include "mps_common.h"
+#include "mps_error.h"
+
+struct mbedtls_mps_reader;
+typedef struct mbedtls_mps_reader mbedtls_mps_reader;
+
+/*
+ * Structure definitions
+ */
+
+struct mbedtls_mps_reader
+{
+ unsigned char *frag; /*!< The fragment of incoming data managed by
+ * the reader; it is provided to the reader
+ * through mbedtls_mps_reader_feed(). The reader
+ * does not own the fragment and does not
+ * perform any allocation operations on it,
+ * but does have read and write access to it.
+ *
+ * The reader is in consuming mode if
+ * and only if \c frag is not \c NULL. */
+ mbedtls_mps_stored_size_t frag_len;
+ /*!< The length of the current fragment.
+ * Must be 0 if \c frag == \c NULL. */
+ mbedtls_mps_stored_size_t commit;
+ /*!< The offset of the last commit, relative
+ * to the first byte in the fragment, if
+ * no accumulator is present. If an accumulator
+ * is present, it is viewed as a prefix to the
+ * current fragment, and this variable contains
+ * an offset from the beginning of the accumulator.
+ *
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+ mbedtls_mps_stored_size_t end;
+ /*!< The offset of the end of the last chunk
+ * passed to the user through a call to
+ * mbedtls_mps_reader_get(), relative to the first
+ * byte in the fragment, if no accumulator is
+ * present. If an accumulator is present, it is
+ * viewed as a prefix to the current fragment, and
+ * this variable contains an offset from the
+ * beginning of the accumulator.
+ *
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+ mbedtls_mps_stored_size_t pending;
+ /*!< The amount of incoming data missing on the
+ * last call to mbedtls_mps_reader_get().
+ * In particular, it is \c 0 if the last call
+ * was successful.
+ * If a reader is reclaimed after an
+ * unsuccessful call to mbedtls_mps_reader_get(),
+ * this variable is used to have the reader
+ * remember how much data should be accumulated
+ * so that the call to mbedtls_mps_reader_get()
+ * succeeds next time.
+ * This is only used when the reader is in
+ * consuming mode, i.e. \c frag != \c NULL;
+ * otherwise, its value is \c 0. */
+
+ /* The accumulator is only needed if we need to be able to pause
+ * the reader. A few bytes could be saved by moving this to a
+ * separate struct and using a pointer here. */
+
+ unsigned char *acc; /*!< The accumulator is used to gather incoming
+ * data if a read-request via mbedtls_mps_reader_get()
+ * cannot be served from the current fragment. */
+ mbedtls_mps_stored_size_t acc_len;
+ /*!< The total size of the accumulator. */
+ mbedtls_mps_stored_size_t acc_available;
+ /*!< The number of bytes currently gathered in
+ * the accumulator. This is both used in
+ * producing and in consuming mode:
+ * While producing, it is increased until
+ * it reaches the value of \c acc_remaining below.
+ * While consuming, it is used to judge if a
+ * get request can be served from the
+ * accumulator or not.
+ * Must not be larger than \c acc_len. */
+ union
+ {
+ mbedtls_mps_stored_size_t acc_remaining;
+ /*!< This indicates the amount of data still
+ * to be gathered in the accumulator. It is
+ * only used in producing mode.
+ * Must be at most acc_len - acc_available. */
+ mbedtls_mps_stored_size_t frag_offset;
+ /*!< If an accumulator is present and in use, this
+ * field indicates the offset of the current
+ * fragment from the beginning of the
+ * accumulator. If no accumulator is present
+ * or the accumulator is not in use, this is \c 0.
+ * It is only used in consuming mode.
+ * Must not be larger than \c acc_available. */
+ } acc_share;
+};
+
+/*
+ * API organization:
+ * A reader object is usually prepared and maintained
+ * by some lower layer and passed for usage to an upper
+ * layer, and the API naturally splits according to which
+ * layer is supposed to use the respective functions.
+ */
+
+/*
+ * Maintenance API (Lower layer)
+ */
+
+/**
+ * \brief Initialize a reader object
+ *
+ * \param reader The reader to be initialized.
+ * \param acc The buffer to be used as a temporary accumulator
+ * in case get requests through mbedtls_mps_reader_get()
+ * exceed the buffer provided by mbedtls_mps_reader_feed().
+ * This buffer is owned by the caller and exclusive use
+ * for reading and writing is given to the reader for the
+ * duration of the reader's lifetime. It is thus the caller's
+ * responsibility to maintain (and not touch) the buffer for
+ * the lifetime of the reader, and to properly zeroize and
+ * free the memory after the reader has been destroyed.
+ * \param acc_len The size in Bytes of \p acc.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_init( mbedtls_mps_reader *reader,
+ unsigned char *acc,
+ mbedtls_mps_size_t acc_len );
+
+/**
+ * \brief Free a reader object
+ *
+ * \param reader The reader to be freed.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_free( mbedtls_mps_reader *reader );
+
+/**
+ * \brief Pass chunk of data for the reader to manage.
+ *
+ * \param reader The reader context to use. The reader must be
+ * in producing mode.
+ * \param buf The buffer to be managed by the reader.
+ * \param buflen The size in Bytes of \p buffer.
+ *
+ * \return \c 0 on success. In this case, the reader will be
+ * moved to consuming mode and obtains read access
+ * of \p buf until mbedtls_mps_reader_reclaim()
+ * is called. It is the responsibility of the caller
+ * to ensure that the \p buf persists and is not changed
+ * between successful calls to mbedtls_mps_reader_feed()
+ * and mbedtls_mps_reader_reclaim().
+ * \return \c MBEDTLS_ERR_MPS_READER_NEED_MORE if more input data is
+ * required to fulfill a previous request to mbedtls_mps_reader_get().
+ * In this case, the reader remains in producing mode and
+ * takes no ownership of the provided buffer (an internal copy
+ * is made instead).
+ * \return Another negative \c MBEDTLS_ERR_READER_XXX error code on
+ * different kinds of failures.
+ */
+int mbedtls_mps_reader_feed( mbedtls_mps_reader *reader,
+ unsigned char *buf,
+ mbedtls_mps_size_t buflen );
+
+/**
+ * \brief Reclaim reader's access to the current input buffer.
+ *
+ * \param reader The reader context to use. The reader must be
+ * in consuming mode.
+ * \param paused If not \c NULL, the integer at address \p paused will be
+ * modified to indicate whether the reader has been paused
+ * (value \c 1) or not (value \c 0). Pausing happens if there
+ * is uncommitted data and a previous request to
+ * mbedtls_mps_reader_get() has exceeded the bounds of the
+ * input buffer.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ */
+int mbedtls_mps_reader_reclaim( mbedtls_mps_reader *reader,
+ int *paused );
+
+/*
+ * Usage API (Upper layer)
+ */
+
+/**
+ * \brief Request data from the reader.
+ *
+ * \param reader The reader context to use. The reader must
+ * be in consuming mode.
+ * \param desired The desired amount of data to be read, in Bytes.
+ * \param buffer The address to store the buffer pointer in.
+ * This must not be \c NULL.
+ * \param buflen The address to store the actual buffer
+ * length in, or \c NULL.
+ *
+ * \return \c 0 on success. In this case, \c *buf holds the
+ * address of a buffer of size \c *buflen
+ * (if \c buflen != \c NULL) or \c desired
+ * (if \c buflen == \c NULL). The user has read access
+ * to the buffer and guarantee of stability of the data
+ * until the next call to mbedtls_mps_reader_reclaim().
+ * \return #MBEDTLS_ERR_MPS_READER_OUT_OF_DATA if there is not enough
+ * data available to serve the get request. In this case, the
+ * reader remains intact and in consuming mode, and the consumer
+ * should retry the call after a successful cycle of
+ * mbedtls_mps_reader_reclaim() and mbedtls_mps_reader_feed().
+ * If, after such a cycle, the consumer requests a different
+ * amount of data, the result is implementation-defined;
+ * progress is guaranteed only if the same amount of data
+ * is requested after a mbedtls_mps_reader_reclaim() and
+ * mbedtls_mps_reader_feed() cycle.
+ * \return Another negative \c MBEDTLS_ERR_READER_XXX error
+ * code for different kinds of failure.
+ *
+ * \note Passing \c NULL as \p buflen is a convenient way to
+ * indicate that fragmentation is not tolerated.
+ * It's functionally equivalent to passing a valid
+ * address as buflen and checking \c *buflen == \c desired
+ * afterwards.
+ */
+int mbedtls_mps_reader_get( mbedtls_mps_reader *reader,
+ mbedtls_mps_size_t desired,
+ unsigned char **buffer,
+ mbedtls_mps_size_t *buflen );
+
+/**
+ * \brief Mark data obtained from mbedtls_mps_reader_get() as processed.
+ *
+ * This call indicates that all data received from prior calls to
+ * mbedtls_mps_reader_get() has been or will have been
+ * processed when mbedtls_mps_reader_reclaim() is called,
+ * and thus need not be backed up.
+ *
+ * This function has no user observable effect until
+ * mbedtls_mps_reader_reclaim() is called. In particular,
+ * buffers received from mbedtls_mps_reader_get() remain
+ * valid until mbedtls_mps_reader_reclaim() is called.
+ *
+ * \param reader The reader context to use.
+ *
+ * \return \c 0 on success.
+ * \return A negative \c MBEDTLS_ERR_READER_XXX error code on failure.
+ *
+ */
+int mbedtls_mps_reader_commit( mbedtls_mps_reader *reader );
+
+#endif /* MBEDTLS_READER_H */
diff --git a/thirdparty/mbedtls/library/mps_trace.c b/thirdparty/mbedtls/library/mps_trace.c
new file mode 100644
index 0000000000..6026a07163
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_trace.c
@@ -0,0 +1,127 @@
+/*
+ * Message Processing Stack, Trace module
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of Mbed TLS (https://tls.mbed.org)
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mps_common.h"
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+
+#include "mps_trace.h"
+#include <stdarg.h>
+
+static int trace_depth = 0;
+
+#define color_default "\x1B[0m"
+#define color_red "\x1B[1;31m"
+#define color_green "\x1B[1;32m"
+#define color_yellow "\x1B[1;33m"
+#define color_blue "\x1B[1;34m"
+#define color_magenta "\x1B[1;35m"
+#define color_cyan "\x1B[1;36m"
+#define color_white "\x1B[1;37m"
+
+static char const * colors[] =
+{
+ color_default,
+ color_green,
+ color_yellow,
+ color_magenta,
+ color_cyan,
+ color_blue,
+ color_white
+};
+
+#define MPS_TRACE_BUF_SIZE 100
+
+void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... )
+{
+ int ret;
+ char str[MPS_TRACE_BUF_SIZE];
+ va_list argp;
+ va_start( argp, format );
+ ret = mbedtls_vsnprintf( str, MPS_TRACE_BUF_SIZE, format, argp );
+ va_end( argp );
+
+ if( ret >= 0 && ret < MPS_TRACE_BUF_SIZE )
+ {
+ str[ret] = '\0';
+ mbedtls_printf( "[%d|L%d]: %s\n", id, line, str );
+ }
+}
+
+int mbedtls_mps_trace_get_depth()
+{
+ return trace_depth;
+}
+void mbedtls_mps_trace_dec_depth()
+{
+ trace_depth--;
+}
+void mbedtls_mps_trace_inc_depth()
+{
+ trace_depth++;
+}
+
+void mbedtls_mps_trace_color( int id )
+{
+ if( id > (int) ( sizeof( colors ) / sizeof( *colors ) ) )
+ return;
+ printf( "%s", colors[ id ] );
+}
+
+void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty )
+{
+ if( level > 0 )
+ {
+ while( --level )
+ printf( "| " );
+
+ printf( "| " );
+ }
+
+ switch( ty )
+ {
+ case MBEDTLS_MPS_TRACE_TYPE_COMMENT:
+ mbedtls_printf( "@ " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_CALL:
+ mbedtls_printf( "+--> " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_ERROR:
+ mbedtls_printf( "E " );
+ break;
+
+ case MBEDTLS_MPS_TRACE_TYPE_RETURN:
+ mbedtls_printf( "< " );
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif /* MBEDTLS_MPS_ENABLE_TRACE */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/mps_trace.h b/thirdparty/mbedtls/library/mps_trace.h
new file mode 100644
index 0000000000..7c2360118a
--- /dev/null
+++ b/thirdparty/mbedtls/library/mps_trace.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/**
+ * \file mps_trace.h
+ *
+ * \brief Tracing module for MPS
+ */
+
+#ifndef MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
+#define MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H
+
+#include "common.h"
+#include "mps_common.h"
+#include "mps_trace.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#define mbedtls_vsnprintf vsnprintf
+#endif /* MBEDTLS_PLATFORM_C */
+
+#if defined(MBEDTLS_MPS_ENABLE_TRACE)
+
+/*
+ * Adapt this to enable/disable tracing output
+ * from the various layers of the MPS.
+ */
+
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_1
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_2
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_3
+#define MBEDTLS_MPS_TRACE_ENABLE_LAYER_4
+#define MBEDTLS_MPS_TRACE_ENABLE_READER
+#define MBEDTLS_MPS_TRACE_ENABLE_WRITER
+
+/*
+ * To use the existing trace module, only change
+ * MBEDTLS_MPS_TRACE_ENABLE_XXX above, but don't modify the
+ * rest of this file.
+ */
+
+typedef enum
+{
+ MBEDTLS_MPS_TRACE_TYPE_COMMENT,
+ MBEDTLS_MPS_TRACE_TYPE_CALL,
+ MBEDTLS_MPS_TRACE_TYPE_ERROR,
+ MBEDTLS_MPS_TRACE_TYPE_RETURN
+} mbedtls_mps_trace_type;
+
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_1 1
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_2 2
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_3 3
+#define MBEDTLS_MPS_TRACE_BIT_LAYER_4 4
+#define MBEDTLS_MPS_TRACE_BIT_WRITER 5
+#define MBEDTLS_MPS_TRACE_BIT_READER 6
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_1)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_1 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_1 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_2)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_2 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_2 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_3)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_3 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_3 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_LAYER_4)
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 (1u << MBEDTLS_MPS_TRACE_BIT_LAYER_4 )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_LAYER_4 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_READER)
+#define MBEDTLS_MPS_TRACE_MASK_READER (1u << MBEDTLS_MPS_TRACE_BIT_READER )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_READER 0
+#endif
+
+#if defined(MBEDTLS_MPS_TRACE_ENABLE_WRITER)
+#define MBEDTLS_MPS_TRACE_MASK_WRITER (1u << MBEDTLS_MPS_TRACE_BIT_WRITER )
+#else
+#define MBEDTLS_MPS_TRACE_MASK_WRITER 0
+#endif
+
+#define MBEDTLS_MPS_TRACE_MASK ( MBEDTLS_MPS_TRACE_MASK_LAYER_1 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_2 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_3 | \
+ MBEDTLS_MPS_TRACE_MASK_LAYER_4 | \
+ MBEDTLS_MPS_TRACE_MASK_READER | \
+ MBEDTLS_MPS_TRACE_MASK_WRITER )
+
+/* We have to avoid globals because E-ACSL chokes on them...
+ * Wrap everything in stub functions. */
+int mbedtls_mps_trace_get_depth( void );
+void mbedtls_mps_trace_inc_depth( void );
+void mbedtls_mps_trace_dec_depth( void );
+
+void mbedtls_mps_trace_color( int id );
+void mbedtls_mps_trace_indent( int level, mbedtls_mps_trace_type ty );
+
+void mbedtls_mps_trace_print_msg( int id, int line, const char *format, ... );
+
+#define MBEDTLS_MPS_TRACE( type, ... ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ mbedtls_mps_trace_indent( mbedtls_mps_trace_get_depth(), type ); \
+ mbedtls_mps_trace_color( mbedtls_mps_trace_id ); \
+ mbedtls_mps_trace_print_msg( mbedtls_mps_trace_id, __LINE__, __VA_ARGS__ ); \
+ mbedtls_mps_trace_color( 0 ); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_INIT( ... ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_CALL, __VA_ARGS__ ); \
+ mbedtls_mps_trace_inc_depth(); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_END( val ) \
+ do { \
+ if( ! ( MBEDTLS_MPS_TRACE_MASK & ( 1u << mbedtls_mps_trace_id ) ) ) \
+ break; \
+ MBEDTLS_MPS_TRACE( MBEDTLS_MPS_TRACE_TYPE_RETURN, "%d (-%#04x)", \
+ (int) (val), -((unsigned)(val)) ); \
+ mbedtls_mps_trace_dec_depth(); \
+ } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_RETURN( val ) \
+ do { \
+ /* Breaks tail recursion. */ \
+ int ret__ = val; \
+ MBEDTLS_MPS_TRACE_END( ret__ ); \
+ return( ret__ ); \
+ } while( 0 )
+
+#else /* MBEDTLS_MPS_TRACE */
+
+#define MBEDTLS_MPS_TRACE( type, ... ) do { } while( 0 )
+#define MBEDTLS_MPS_TRACE_INIT( ... ) do { } while( 0 )
+#define MBEDTLS_MPS_TRACE_END do { } while( 0 )
+
+#define MBEDTLS_MPS_TRACE_RETURN( val ) return( val );
+
+#endif /* MBEDTLS_MPS_TRACE */
+
+#endif /* MBEDTLS_MPS_MBEDTLS_MPS_TRACE_H */
diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c
index 1e701a5000..5fbe1f764a 100644
--- a/thirdparty/mbedtls/library/net_sockets.c
+++ b/thirdparty/mbedtls/library/net_sockets.c
@@ -2,13 +2,7 @@
* TCP/IP or UDP/IP networking functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must
@@ -50,24 +23,17 @@
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#endif
-
-#if defined(__NetBSD__)
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* sockaddr_storage */
#endif
-#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_NET_C)
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
#endif
@@ -78,6 +44,7 @@
#endif
#include "mbedtls/net_sockets.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -86,8 +53,7 @@
#define IS_EINTR( ret ) ( ( ret ) == WSAEINTR )
-#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
-#undef _WIN32_WINNT
+#if !defined(_WIN32_WINNT)
/* Enables getaddrinfo() & Co */
#define _WIN32_WINNT 0x0501
#endif
@@ -96,6 +62,9 @@
#include <winsock2.h>
#include <windows.h>
+#if (_WIN32_WINNT < 0x0501)
+#include <wspiapi.h>
+#endif
#if defined(_MSC_VER)
#if defined(_WIN32_WCE)
@@ -205,7 +174,7 @@ void mbedtls_net_init( mbedtls_net_context *ctx )
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
const char *port, int proto )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct addrinfo hints, *addr_list, *cur;
if( ( ret = net_prepare() ) != 0 )
@@ -371,14 +340,14 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
mbedtls_net_context *client_ctx,
void *client_ip, size_t buf_size, size_t *ip_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int type;
struct sockaddr_storage client_addr;
-#if defined(__socklen_t_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) )
+ defined(socklen_t) || (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L)
socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type );
#else
@@ -514,7 +483,7 @@ int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
int mbedtls_net_poll( mbedtls_net_context *ctx, uint32_t rw, uint32_t timeout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct timeval tv;
fd_set read_fds;
@@ -600,7 +569,7 @@ void mbedtls_net_usleep( unsigned long usec )
*/
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int fd = ((mbedtls_net_context *) ctx)->fd;
ret = check_fd( fd, 0 );
@@ -638,7 +607,7 @@ int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
size_t len, uint32_t timeout )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
struct timeval tv;
fd_set read_fds;
int fd = ((mbedtls_net_context *) ctx)->fd;
@@ -682,7 +651,7 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf,
*/
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int fd = ((mbedtls_net_context *) ctx)->fd;
ret = check_fd( fd, 0 );
@@ -715,6 +684,19 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
}
/*
+ * Close the connection
+ */
+void mbedtls_net_close( mbedtls_net_context *ctx )
+{
+ if( ctx->fd == -1 )
+ return;
+
+ close( ctx->fd );
+
+ ctx->fd = -1;
+}
+
+/*
* Gracefully close the connection
*/
void mbedtls_net_free( mbedtls_net_context *ctx )
diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c
index 278b7e91ab..1aea0b6345 100644
--- a/thirdparty/mbedtls/library/nist_kw.c
+++ b/thirdparty/mbedtls/library/nist_kw.c
@@ -3,13 +3,7 @@
* only
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,27 +16,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* Definition of Key Wrapping:
@@ -54,16 +27,14 @@
* the wrapping and unwrapping operation than the definition in NIST SP 800-38F.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_NIST_KW_C)
#include "mbedtls/nist_kw.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
#include <stdint.h>
#include <string.h>
@@ -82,51 +53,11 @@
#define KW_SEMIBLOCK_LENGTH 8
#define MIN_SEMIBLOCKS_COUNT 3
-/* constant-time buffer comparison */
-static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- volatile const unsigned char *A = (volatile const unsigned char *) a;
- volatile const unsigned char *B = (volatile const unsigned char *) b;
- volatile unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- {
- /* Read volatile data in order before computing diff.
- * This avoids IAR compiler warning:
- * 'the order of volatile accesses is undefined ..' */
- unsigned char x = A[i], y = B[i];
- diff |= x ^ y;
- }
-
- return( diff );
-}
-
/*! The 64-bit default integrity check value (ICV) for KW mode. */
static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6};
/*! The 32-bit default integrity check value (ICV) for KWP mode. */
static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6};
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-do { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-do { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-} while( 0 )
-#endif
-
/*
* Initialize context
*/
@@ -141,7 +72,7 @@ int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx,
unsigned int keybits,
const int is_wrap )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values( cipher,
@@ -273,7 +204,7 @@ int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx,
}
memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 );
- PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
+ MBEDTLS_PUT_UINT32_BE( ( in_len & 0xffffffff ), output,
KW_SEMIBLOCK_LENGTH / 2 );
memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len );
@@ -448,7 +379,7 @@ int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
goto cleanup;
/* Check ICV in "constant-time" */
- diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
+ diff = mbedtls_ct_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH );
if( diff != 0 )
{
@@ -497,14 +428,14 @@ int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx,
}
/* Check ICV in "constant-time" */
- diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
+ diff = mbedtls_ct_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 );
if( diff != 0 )
{
ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED;
}
- GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 );
+ Plen = MBEDTLS_GET_UINT32_BE( A, KW_SEMIBLOCK_LENGTH / 2 );
/*
* Plen is the length of the plaintext, when the input is valid.
diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c
index 2414083f0c..19c8ac207c 100644
--- a/thirdparty/mbedtls/library/oid.c
+++ b/thirdparty/mbedtls/library/oid.c
@@ -4,13 +4,7 @@
* \brief Object Identifier (OID) database
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,39 +17,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_OID_C)
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
+#include "mbedtls/error.h"
#include <stdio.h>
#include <string.h>
@@ -66,10 +36,6 @@
#define mbedtls_snprintf snprintf
#endif
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
-#include "mbedtls/x509.h"
-#endif
-
/*
* Macro to automatically add the size of #define'd OIDs
*/
@@ -180,7 +146,6 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
return( MBEDTLS_ERR_OID_NOT_FOUND ); \
}
-#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
/*
* For X520 attribute types
*/
@@ -287,24 +252,28 @@ typedef struct {
static const oid_x509_ext_t oid_x509_ext[] =
{
{
- { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
- MBEDTLS_X509_EXT_BASIC_CONSTRAINTS,
+ { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" },
+ MBEDTLS_OID_X509_EXT_BASIC_CONSTRAINTS,
+ },
+ {
+ { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
+ MBEDTLS_OID_X509_EXT_KEY_USAGE,
},
{
- { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" },
- MBEDTLS_X509_EXT_KEY_USAGE,
+ { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
+ MBEDTLS_OID_X509_EXT_EXTENDED_KEY_USAGE,
},
{
- { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
- MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
+ { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
+ MBEDTLS_OID_X509_EXT_SUBJECT_ALT_NAME,
},
{
- { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" },
- MBEDTLS_X509_EXT_SUBJECT_ALT_NAME,
+ { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
+ MBEDTLS_OID_X509_EXT_NS_CERT_TYPE,
},
{
- { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" },
- MBEDTLS_X509_EXT_NS_CERT_TYPE,
+ { ADD_LEN( MBEDTLS_OID_CERTIFICATE_POLICIES ), "id-ce-certificatePolicies", "Certificate Policies" },
+ MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES,
},
{
{ NULL, 0, NULL, NULL },
@@ -317,18 +286,27 @@ FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, e
static const mbedtls_oid_descriptor_t oid_ext_key_usage[] =
{
- { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
- { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
- { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
- { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
- { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
- { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
+ { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" },
+ { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" },
+ { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" },
+ { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" },
+ { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" },
+ { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" },
+ { ADD_LEN( MBEDTLS_OID_WISUN_FAN ), "id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)" },
{ NULL, 0, NULL, NULL },
};
FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage)
FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description)
-#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
+
+static const mbedtls_oid_descriptor_t oid_certificate_policies[] =
+{
+ { ADD_LEN( MBEDTLS_OID_ANY_POLICY ), "anyPolicy", "Any Policy" },
+ { NULL, 0, NULL, NULL },
+};
+
+FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, certificate_policies, oid_certificate_policies)
+FN_OID_GET_ATTR1(mbedtls_oid_get_certificate_policies, mbedtls_oid_descriptor_t, certificate_policies, const char *, description)
#if defined(MBEDTLS_MD_C)
/*
@@ -644,6 +622,12 @@ static const oid_md_alg_t oid_md_alg[] =
MBEDTLS_MD_SHA512,
},
#endif /* MBEDTLS_SHA512_C */
+#if defined(MBEDTLS_RIPEMD160_C)
+ {
+ { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_RIPEMD160 ), "id-ripemd160", "RIPEMD-160" },
+ MBEDTLS_MD_RIPEMD160,
+ },
+#endif /* MBEDTLS_RIPEMD160_C */
{
{ NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE,
@@ -743,7 +727,7 @@ FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pb
int mbedtls_oid_get_numeric_string( char *buf, size_t size,
const mbedtls_asn1_buf *oid )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n;
unsigned int value;
char *p;
@@ -771,7 +755,7 @@ int mbedtls_oid_get_numeric_string( char *buf, size_t size,
if( !( oid->p[i] & 0x80 ) )
{
/* Last byte */
- ret = mbedtls_snprintf( p, n, ".%d", value );
+ ret = mbedtls_snprintf( p, n, ".%u", value );
OID_SAFE_SNPRINTF;
value = 0;
}
diff --git a/thirdparty/mbedtls/library/padlock.c b/thirdparty/mbedtls/library/padlock.c
index afb7e0ad42..837337413c 100644
--- a/thirdparty/mbedtls/library/padlock.c
+++ b/thirdparty/mbedtls/library/padlock.c
@@ -2,13 +2,7 @@
* VIA PadLock support functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* This implementation is based on the VIA PadLock Programming Guide:
@@ -50,11 +23,7 @@
* programming_guide.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PADLOCK_C)
@@ -83,10 +52,10 @@ int mbedtls_padlock_has_support( int feature )
"cpuid \n\t"
"cmpl $0xC0000001, %%eax \n\t"
"movl $0, %%edx \n\t"
- "jb unsupported \n\t"
+ "jb 1f \n\t"
"movl $0xC0000001, %%eax \n\t"
"cpuid \n\t"
- "unsupported: \n\t"
+ "1: \n\t"
"movl %%edx, %1 \n\t"
"movl %2, %%ebx \n\t"
: "=m" (ebx), "=m" (edx)
diff --git a/thirdparty/mbedtls/library/pem.c b/thirdparty/mbedtls/library/pem.c
index 50e663ccdb..fcfde94799 100644
--- a/thirdparty/mbedtls/library/pem.c
+++ b/thirdparty/mbedtls/library/pem.c
@@ -2,13 +2,7 @@
* Privacy Enhanced Mail (PEM) decoding
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
@@ -59,6 +28,7 @@
#include "mbedtls/md5.h"
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -110,7 +80,7 @@ static int pem_pbkdf1( unsigned char *key, size_t keylen,
mbedtls_md5_context md5_ctx;
unsigned char md5sum[16];
size_t use_len;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md5_init( &md5_ctx );
@@ -171,7 +141,7 @@ static int pem_des_decrypt( unsigned char des_iv[8],
{
mbedtls_des_context des_ctx;
unsigned char des_key[8];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_des_init( &des_ctx );
@@ -199,7 +169,7 @@ static int pem_des3_decrypt( unsigned char des3_iv[8],
{
mbedtls_des3_context des3_ctx;
unsigned char des3_key[24];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_des3_init( &des3_ctx );
@@ -229,7 +199,7 @@ static int pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
{
mbedtls_aes_context aes_ctx;
unsigned char aes_key[32];
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_aes_init( &aes_ctx );
@@ -373,7 +343,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PEM_INVALID_DATA, ret ) );
if( ( buf = mbedtls_calloc( 1, len ) ) == NULL )
return( MBEDTLS_ERR_PEM_ALLOC_FAILED );
@@ -382,7 +352,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
{
mbedtls_platform_zeroize( buf, len );
mbedtls_free( buf );
- return( MBEDTLS_ERR_PEM_INVALID_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PEM_INVALID_DATA, ret ) );
}
if( enc != 0 )
@@ -464,7 +434,7 @@ int mbedtls_pem_write_buffer( const char *header, const char *footer,
const unsigned char *der_data, size_t der_len,
unsigned char *buf, size_t buf_len, size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *encode_buf = NULL, *c, *p = buf;
size_t len = 0, use_len, add_len = 0;
diff --git a/thirdparty/mbedtls/library/pk.c b/thirdparty/mbedtls/library/pk.c
index 8998271b97..05cc2134f1 100644
--- a/thirdparty/mbedtls/library/pk.c
+++ b/thirdparty/mbedtls/library/pk.c
@@ -2,13 +2,7 @@
* Public Key abstraction layer
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,40 +15,16 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk.h"
#include "mbedtls/pk_internal.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_RSA_C)
#include "mbedtls/rsa.h"
@@ -66,6 +36,10 @@
#include "mbedtls/ecdsa.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#endif
+
#include <limits.h>
#include <stdint.h>
@@ -172,6 +146,42 @@ int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info )
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * Initialise a PSA-wrapping context
+ */
+int mbedtls_pk_setup_opaque( mbedtls_pk_context *ctx,
+ const psa_key_id_t key )
+{
+ const mbedtls_pk_info_t * const info = &mbedtls_pk_opaque_info;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t *pk_ctx;
+ psa_key_type_t type;
+
+ if( ctx == NULL || ctx->pk_info != NULL )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ if( PSA_SUCCESS != psa_get_key_attributes( key, &attributes ) )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+ type = psa_get_key_type( &attributes );
+ psa_reset_key_attributes( &attributes );
+
+ /* Current implementation of can_do() relies on this. */
+ if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( type ) )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ;
+
+ if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL )
+ return( MBEDTLS_ERR_PK_ALLOC_FAILED );
+
+ ctx->pk_info = info;
+
+ pk_ctx = (psa_key_id_t *) ctx->pk_ctx;
+ *pk_ctx = key;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
/*
* Initialize an RSA-alt context
@@ -231,7 +241,7 @@ static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len
if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL )
return( -1 );
- if ( *hash_len != 0 && *hash_len < mbedtls_md_get_size( md_info ) )
+ if ( *hash_len != 0 && *hash_len != mbedtls_md_get_size( md_info ) )
return ( -1 );
*hash_len = mbedtls_md_get_size( md_info );
@@ -286,7 +296,7 @@ int mbedtls_pk_verify_restartable( mbedtls_pk_context *ctx,
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->verify_rs_func != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
@@ -343,7 +353,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
if( type == MBEDTLS_PK_RSASSA_PSS )
{
#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_rsassa_pss_options *pss_opts;
#if SIZE_MAX > UINT_MAX
@@ -409,7 +419,7 @@ int mbedtls_pk_sign_restartable( mbedtls_pk_context *ctx,
mbedtls_ecp_restart_is_enabled() &&
ctx->pk_info->sign_rs_func != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = pk_restart_setup( rs_ctx, ctx->pk_info ) ) != 0 )
return( ret );
@@ -500,12 +510,14 @@ int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_conte
PK_VALIDATE_RET( prv != NULL );
if( pub->pk_info == NULL ||
- prv->pk_info == NULL ||
- prv->pk_info->check_pair_func == NULL )
+ prv->pk_info == NULL )
{
return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
}
+ if( prv->pk_info->check_pair_func == NULL )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT )
{
if( pub->pk_info->type != MBEDTLS_PK_RSA )
@@ -571,4 +583,60 @@ mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx )
return( ctx->pk_info->type );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * Load the key to a PSA key slot,
+ * then turn the PK context into a wrapper for that key slot.
+ *
+ * Currently only works for EC private keys.
+ */
+int mbedtls_pk_wrap_as_opaque( mbedtls_pk_context *pk,
+ psa_key_id_t *key,
+ psa_algorithm_t hash_alg )
+{
+#if !defined(MBEDTLS_ECP_C)
+ ((void) pk);
+ ((void) key);
+ ((void) hash_alg);
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+#else
+ const mbedtls_ecp_keypair *ec;
+ unsigned char d[MBEDTLS_ECP_MAX_BYTES];
+ size_t d_len;
+ psa_ecc_family_t curve_id;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t key_type;
+ size_t bits;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* export the private key material in the format PSA wants */
+ if( mbedtls_pk_get_type( pk ) != MBEDTLS_PK_ECKEY )
+ return( MBEDTLS_ERR_PK_TYPE_MISMATCH );
+
+ ec = mbedtls_pk_ec( *pk );
+ d_len = ( ec->grp.nbits + 7 ) / 8;
+ if( ( ret = mbedtls_mpi_write_binary( &ec->d, d, d_len ) ) != 0 )
+ return( ret );
+
+ curve_id = mbedtls_ecc_group_to_psa( ec->grp.id, &bits );
+ key_type = PSA_KEY_TYPE_ECC_KEY_PAIR( curve_id );
+
+ /* prepare the key attributes */
+ psa_set_key_type( &attributes, key_type );
+ psa_set_key_bits( &attributes, bits );
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
+ psa_set_key_algorithm( &attributes, PSA_ALG_ECDSA(hash_alg) );
+
+ /* import private key into PSA */
+ if( PSA_SUCCESS != psa_import_key( &attributes, d, d_len, key ) )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+
+ /* make PK context wrap the key slot */
+ mbedtls_pk_free( pk );
+ mbedtls_pk_init( pk );
+
+ return( mbedtls_pk_setup_opaque( pk, *key ) );
+#endif /* MBEDTLS_ECP_C */
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#endif /* MBEDTLS_PK_C */
diff --git a/thirdparty/mbedtls/library/pk_wrap.c b/thirdparty/mbedtls/library/pk_wrap.c
index 2c27552d9b..107e912ace 100644
--- a/thirdparty/mbedtls/library/pk_wrap.c
+++ b/thirdparty/mbedtls/library/pk_wrap.c
@@ -2,13 +2,7 @@
* Public Key abstraction layer: wrapper functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,37 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_C)
#include "mbedtls/pk_internal.h"
+#include "mbedtls/error.h"
/* Even if RSA not activated, for the sake of RSA-alt */
#include "mbedtls/rsa.h"
@@ -66,10 +36,20 @@
#include "mbedtls/ecdsa.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/asn1write.h"
+#endif
+
#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
#include "mbedtls/platform_util.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#include "mbedtls/asn1.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -98,7 +78,7 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_rsa_context * rsa = (mbedtls_rsa_context *) ctx;
size_t rsa_len = mbedtls_rsa_get_len( rsa );
@@ -263,7 +243,7 @@ static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
@@ -281,7 +261,7 @@ static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
unsigned char *sig, size_t *sig_len,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init( &ecdsa );
@@ -355,7 +335,7 @@ static int eckey_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
@@ -380,7 +360,7 @@ static int eckey_sign_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
eckey_restart_ctx *rs = rs_ctx;
/* Should never happen */
@@ -497,11 +477,153 @@ static int ecdsa_can_do( mbedtls_pk_type_t type )
return( type == MBEDTLS_PK_ECDSA );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+/*
+ * An ASN.1 encoded signature is a sequence of two ASN.1 integers. Parse one of
+ * those integers and convert it to the fixed-length encoding expected by PSA.
+ */
+static int extract_ecdsa_sig_int( unsigned char **from, const unsigned char *end,
+ unsigned char *to, size_t to_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t unpadded_len, padding_len;
+
+ if( ( ret = mbedtls_asn1_get_tag( from, end, &unpadded_len,
+ MBEDTLS_ASN1_INTEGER ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ while( unpadded_len > 0 && **from == 0x00 )
+ {
+ ( *from )++;
+ unpadded_len--;
+ }
+
+ if( unpadded_len > to_len || unpadded_len == 0 )
+ return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+
+ padding_len = to_len - unpadded_len;
+ memset( to, 0x00, padding_len );
+ memcpy( to + padding_len, *from, unpadded_len );
+ ( *from ) += unpadded_len;
+
+ return( 0 );
+}
+
+/*
+ * Convert a signature from an ASN.1 sequence of two integers
+ * to a raw {r,s} buffer. Note: the provided sig buffer must be at least
+ * twice as big as int_size.
+ */
+static int extract_ecdsa_sig( unsigned char **p, const unsigned char *end,
+ unsigned char *sig, size_t int_size )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t tmp_size;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &tmp_size,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( ret );
+
+ /* Extract r */
+ if( ( ret = extract_ecdsa_sig_int( p, end, sig, int_size ) ) != 0 )
+ return( ret );
+ /* Extract s */
+ if( ( ret = extract_ecdsa_sig_int( p, end, sig + int_size, int_size ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+}
+
+static int ecdsa_verify_wrap( void *ctx_arg, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ const unsigned char *sig, size_t sig_len )
+{
+ mbedtls_ecdsa_context *ctx = ctx_arg;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_id_t key_id = 0;
+ psa_status_t status;
+ mbedtls_pk_context key;
+ int key_len;
+ /* see ECP_PUB_DER_MAX_BYTES in pkwrite.c */
+ unsigned char buf[30 + 2 * MBEDTLS_ECP_MAX_BYTES];
+ unsigned char *p;
+ mbedtls_pk_info_t pk_info = mbedtls_eckey_info;
+ psa_algorithm_t psa_sig_md = PSA_ALG_ECDSA_ANY;
+ size_t curve_bits;
+ psa_ecc_family_t curve =
+ mbedtls_ecc_group_to_psa( ctx->grp.id, &curve_bits );
+ const size_t signature_part_size = ( ctx->grp.nbits + 7 ) / 8;
+ ((void) md_alg);
+
+ if( curve == 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ /* mbedtls_pk_write_pubkey() expects a full PK context;
+ * re-construct one to make it happy */
+ key.pk_info = &pk_info;
+ key.pk_ctx = ctx;
+ p = buf + sizeof( buf );
+ key_len = mbedtls_pk_write_pubkey( &p, buf, &key );
+ if( key_len <= 0 )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ psa_set_key_type( &attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY( curve ) );
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
+ psa_set_key_algorithm( &attributes, psa_sig_md );
+
+ status = psa_import_key( &attributes,
+ buf + sizeof( buf ) - key_len, key_len,
+ &key_id );
+ if( status != PSA_SUCCESS )
+ {
+ ret = mbedtls_psa_err_translate_pk( status );
+ goto cleanup;
+ }
+
+ /* We don't need the exported key anymore and can
+ * reuse its buffer for signature extraction. */
+ if( 2 * signature_part_size > sizeof( buf ) )
+ {
+ ret = MBEDTLS_ERR_PK_BAD_INPUT_DATA;
+ goto cleanup;
+ }
+
+ p = (unsigned char*) sig;
+ if( ( ret = extract_ecdsa_sig( &p, sig + sig_len, buf,
+ signature_part_size ) ) != 0 )
+ {
+ goto cleanup;
+ }
+
+ if( psa_verify_hash( key_id, psa_sig_md,
+ hash, hash_len,
+ buf, 2 * signature_part_size )
+ != PSA_SUCCESS )
+ {
+ ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+ goto cleanup;
+ }
+
+ if( p != sig + sig_len )
+ {
+ ret = MBEDTLS_ERR_PK_SIG_LEN_MISMATCH;
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ psa_destroy_key( key_id );
+ return( ret );
+}
+#else /* MBEDTLS_USE_PSA_CRYPTO */
static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
const unsigned char *sig, size_t sig_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx,
@@ -512,6 +634,7 @@ static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
return( ret );
}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *hash, size_t hash_len,
@@ -528,7 +651,7 @@ static int ecdsa_verify_rs_wrap( void *ctx, mbedtls_md_type_t md_alg,
const unsigned char *sig, size_t sig_len,
void *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
((void) md_alg);
ret = mbedtls_ecdsa_read_signature_restartable(
@@ -644,6 +767,8 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
#endif /* SIZE_MAX > UINT_MAX */
*sig_len = rsa_alt->key_len_func( rsa_alt->key );
+ if( *sig_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE,
md_alg, (unsigned int) hash_len, hash, sig ) );
@@ -672,7 +797,7 @@ static int rsa_alt_check_pair( const void *pub, const void *prv )
unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
unsigned char hash[32];
size_t sig_len = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) )
return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
@@ -741,4 +866,204 @@ const mbedtls_pk_info_t mbedtls_rsa_alt_info = {
#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+static void *pk_opaque_alloc_wrap( void )
+{
+ void *ctx = mbedtls_calloc( 1, sizeof( psa_key_id_t ) );
+
+ /* no _init() function to call, an calloc() already zeroized */
+
+ return( ctx );
+}
+
+static void pk_opaque_free_wrap( void *ctx )
+{
+ mbedtls_platform_zeroize( ctx, sizeof( psa_key_id_t ) );
+ mbedtls_free( ctx );
+}
+
+static size_t pk_opaque_get_bitlen( const void *ctx )
+{
+ const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+ size_t bits;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+ if( PSA_SUCCESS != psa_get_key_attributes( *key, &attributes ) )
+ return( 0 );
+
+ bits = psa_get_key_bits( &attributes );
+ psa_reset_key_attributes( &attributes );
+ return( bits );
+}
+
+static int pk_opaque_can_do( mbedtls_pk_type_t type )
+{
+ /* For now opaque PSA keys can only wrap ECC keypairs,
+ * as checked by setup_psa().
+ * Also, ECKEY_DH does not really make sense with the current API. */
+ return( type == MBEDTLS_PK_ECKEY ||
+ type == MBEDTLS_PK_ECDSA );
+}
+
+#if defined(MBEDTLS_ECDSA_C)
+
+/*
+ * Simultaneously convert and move raw MPI from the beginning of a buffer
+ * to an ASN.1 MPI at the end of the buffer.
+ * See also mbedtls_asn1_write_mpi().
+ *
+ * p: pointer to the end of the output buffer
+ * start: start of the output buffer, and also of the mpi to write at the end
+ * n_len: length of the mpi to read from start
+ */
+static int asn1_write_mpibuf( unsigned char **p, unsigned char *start,
+ size_t n_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+
+ if( (size_t)( *p - start ) < n_len )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ len = n_len;
+ *p -= len;
+ memmove( *p, start, len );
+
+ /* ASN.1 DER encoding requires minimal length, so skip leading 0s.
+ * Neither r nor s should be 0, but as a failsafe measure, still detect
+ * that rather than overflowing the buffer in case of a PSA error. */
+ while( len > 0 && **p == 0x00 )
+ {
+ ++(*p);
+ --len;
+ }
+
+ /* this is only reached if the signature was invalid */
+ if( len == 0 )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+
+ /* if the msb is 1, ASN.1 requires that we prepend a 0.
+ * Neither r nor s can be 0, so we can assume len > 0 at all times. */
+ if( **p & 0x80 )
+ {
+ if( *p - start < 1 )
+ return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
+ *--(*p) = 0x00;
+ len += 1;
+ }
+
+ 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_INTEGER ) );
+
+ return( (int) len );
+}
+
+/* Transcode signature from PSA format to ASN.1 sequence.
+ * See ecdsa_signature_to_asn1 in ecdsa.c, but with byte buffers instead of
+ * MPIs, and in-place.
+ *
+ * [in/out] sig: the signature pre- and post-transcoding
+ * [in/out] sig_len: signature length pre- and post-transcoding
+ * [int] buf_len: the available size the in/out buffer
+ */
+static int pk_ecdsa_sig_asn1_from_psa( unsigned char *sig, size_t *sig_len,
+ size_t buf_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len = 0;
+ const size_t rs_len = *sig_len / 2;
+ unsigned char *p = sig + buf_len;
+
+ MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig + rs_len, rs_len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, asn1_write_mpibuf( &p, sig, rs_len ) );
+
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, sig, len ) );
+ MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, sig,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
+
+ memmove( sig, p, len );
+ *sig_len = len;
+
+ return( 0 );
+}
+
+#endif /* MBEDTLS_ECDSA_C */
+
+static int pk_opaque_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
+ const unsigned char *hash, size_t hash_len,
+ unsigned char *sig, size_t *sig_len,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+#if !defined(MBEDTLS_ECDSA_C)
+ ((void) ctx);
+ ((void) md_alg);
+ ((void) hash);
+ ((void) hash_len);
+ ((void) sig);
+ ((void) sig_len);
+ ((void) f_rng);
+ ((void) p_rng);
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+#else /* !MBEDTLS_ECDSA_C */
+ const psa_key_id_t *key = (const psa_key_id_t *) ctx;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_algorithm_t alg = PSA_ALG_ECDSA( mbedtls_psa_translate_md( md_alg ) );
+ size_t buf_len;
+ psa_status_t status;
+
+ /* PSA has its own RNG */
+ (void) f_rng;
+ (void) p_rng;
+
+ /* PSA needs an output buffer of known size, but our API doesn't provide
+ * that information. Assume that the buffer is large enough for a
+ * maximal-length signature with that key (otherwise the application is
+ * buggy anyway). */
+ status = psa_get_key_attributes( *key, &attributes );
+ if( status != PSA_SUCCESS )
+ return( mbedtls_psa_err_translate_pk( status ) );
+ buf_len = MBEDTLS_ECDSA_MAX_SIG_LEN( psa_get_key_bits( &attributes ) );
+ psa_reset_key_attributes( &attributes );
+ if( buf_len > MBEDTLS_PK_SIGNATURE_MAX_SIZE )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ /* make the signature */
+ status = psa_sign_hash( *key, alg, hash, hash_len,
+ sig, buf_len, sig_len );
+ if( status != PSA_SUCCESS )
+ return( mbedtls_psa_err_translate_pk( status ) );
+
+ /* transcode it to ASN.1 sequence */
+ return( pk_ecdsa_sig_asn1_from_psa( sig, sig_len, buf_len ) );
+#endif /* !MBEDTLS_ECDSA_C */
+}
+
+const mbedtls_pk_info_t mbedtls_pk_opaque_info = {
+ MBEDTLS_PK_OPAQUE,
+ "Opaque",
+ pk_opaque_get_bitlen,
+ pk_opaque_can_do,
+ NULL, /* verify - will be done later */
+ pk_opaque_sign_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+ NULL, /* restartable verify - not relevant */
+ NULL, /* restartable sign - not relevant */
+#endif
+ NULL, /* decrypt - will be done later */
+ NULL, /* encrypt - will be done later */
+ NULL, /* check_pair - could be done later or left NULL */
+ pk_opaque_alloc_wrap,
+ pk_opaque_free_wrap,
+#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
+ NULL, /* restart alloc - not relevant */
+ NULL, /* restart free - not relevant */
+#endif
+ NULL, /* debug - could be done later, or even left NULL */
+};
+
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#endif /* MBEDTLS_PK_C */
diff --git a/thirdparty/mbedtls/library/pkcs11.c b/thirdparty/mbedtls/library/pkcs11.c
index cf484b86eb..4deccf3f60 100644
--- a/thirdparty/mbedtls/library/pkcs11.c
+++ b/thirdparty/mbedtls/library/pkcs11.c
@@ -6,13 +6,7 @@
* \author Adriaan de Jong <dejong@fox-it.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,27 +19,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
#include "mbedtls/pkcs11.h"
diff --git a/thirdparty/mbedtls/library/pkcs12.c b/thirdparty/mbedtls/library/pkcs12.c
index 05ade49e93..cacf7dba22 100644
--- a/thirdparty/mbedtls/library/pkcs12.c
+++ b/thirdparty/mbedtls/library/pkcs12.c
@@ -2,13 +2,7 @@
* PKCS#12 Personal Information Exchange Syntax
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The PKCS #12 Personal Information Exchange Syntax Standard v1.1
@@ -50,11 +23,7 @@
* ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PKCS12_C)
@@ -62,6 +31,7 @@
#include "mbedtls/asn1.h"
#include "mbedtls/cipher.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -78,7 +48,7 @@
static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char **p = &params->p;
const unsigned char *end = params->p + params->len;
@@ -90,21 +60,21 @@ static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
*
*/
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) );
salt->p = *p;
*p += salt->len;
if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -170,7 +140,7 @@ int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
((void) output);
return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE );
#else
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[16];
mbedtls_arc4_context ctx;
((void) mode);
@@ -289,7 +259,7 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
const unsigned char *salt, size_t saltlen,
mbedtls_md_type_t md_type, int id, int iterations )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned int j;
unsigned char diversifier[128];
@@ -400,8 +370,8 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
for( i = v; i > 0; i-- )
{
j = salt_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- salt_block[i - 1] = j & 0xFF;
+ c = MBEDTLS_BYTE_1( j );
+ salt_block[i - 1] = MBEDTLS_BYTE_0( j );
}
}
@@ -412,8 +382,8 @@ int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen,
for( i = v; i > 0; i-- )
{
j = pwd_block[i - 1] + hash_block[i - 1] + c;
- c = (unsigned char) (j >> 8);
- pwd_block[i - 1] = j & 0xFF;
+ c = MBEDTLS_BYTE_1( j );
+ pwd_block[i - 1] = MBEDTLS_BYTE_0( j );
}
}
}
diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c
index c4447f1546..2b014d91c8 100644
--- a/thirdparty/mbedtls/library/pkcs5.c
+++ b/thirdparty/mbedtls/library/pkcs5.c
@@ -6,13 +6,7 @@
* \author Mathias Olsson <mathias@kompetensum.com>
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -25,27 +19,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* PKCS#5 includes PBKDF2 and more
@@ -54,15 +27,12 @@
* http://tools.ietf.org/html/rfc6070 (Test vectors)
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PKCS5_C)
#include "mbedtls/pkcs5.h"
+#include "mbedtls/error.h"
#if defined(MBEDTLS_ASN1_PARSE_C)
#include "mbedtls/asn1.h"
@@ -84,14 +54,14 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
mbedtls_asn1_buf *salt, int *iterations,
int *keylen, mbedtls_md_type_t *md_type )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf prf_alg_oid;
unsigned char *p = params->p;
const unsigned char *end = params->p + params->len;
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
/*
* PBKDF2-params ::= SEQUENCE {
* salt OCTET STRING,
@@ -101,14 +71,15 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
* }
*
*/
- if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len,
+ MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
salt->p = p;
p += salt->len;
if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
if( p == end )
return( 0 );
@@ -116,21 +87,21 @@ static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params,
if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 )
{
if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
}
if( p == end )
return( 0 );
if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
if( mbedtls_oid_get_md_hmac( &prf_alg_oid, md_type ) != 0 )
return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE );
if( p != end )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -163,11 +134,12 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
* }
*/
if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
- if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 )
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid,
+ &kdf_alg_params ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
// Only PBKDF2 supported at the moment
//
@@ -188,7 +160,7 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid,
&enc_scheme_params ) ) != 0 )
{
- return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PKCS5_INVALID_FORMAT, ret ) );
}
if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 )
@@ -227,7 +199,8 @@ int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode,
if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 )
goto exit;
- if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 )
+ if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen,
+ (mbedtls_operation_t) mode ) ) != 0 )
goto exit;
if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len,
@@ -242,12 +215,14 @@ exit:
}
#endif /* MBEDTLS_ASN1_PARSE_C */
-int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password,
+int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx,
+ const unsigned char *password,
size_t plen, const unsigned char *salt, size_t slen,
unsigned int iteration_count,
uint32_t key_length, unsigned char *output )
{
- int ret = 0, j;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ int j;
unsigned int i;
unsigned char md1[MBEDTLS_MD_MAX_SIZE];
unsigned char work[MBEDTLS_MD_MAX_SIZE];
@@ -264,13 +239,12 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA );
#endif
+ if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
+ return( ret );
while( key_length )
{
// U1 ends up in work
//
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- goto cleanup;
-
if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 )
goto cleanup;
@@ -280,21 +254,24 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p
if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 )
goto cleanup;
+ if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
+ goto cleanup;
+
memcpy( md1, work, md_size );
for( i = 1; i < iteration_count; i++ )
{
// U2 ends up in md1
//
- if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 )
- goto cleanup;
-
if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 )
goto cleanup;
if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 )
goto cleanup;
+ if( ( ret = mbedtls_md_hmac_reset( ctx ) ) != 0 )
+ goto cleanup;
+
// U1 xor U2
//
for( j = 0; j < md_size; j++ )
@@ -334,10 +311,10 @@ int mbedtls_pkcs5_self_test( int verbose )
#define MAX_TESTS 6
-static const size_t plen[MAX_TESTS] =
+static const size_t plen_test_data[MAX_TESTS] =
{ 8, 8, 8, 24, 9 };
-static const unsigned char password[MAX_TESTS][32] =
+static const unsigned char password_test_data[MAX_TESTS][32] =
{
"password",
"password",
@@ -346,10 +323,10 @@ static const unsigned char password[MAX_TESTS][32] =
"pass\0word",
};
-static const size_t slen[MAX_TESTS] =
+static const size_t slen_test_data[MAX_TESTS] =
{ 4, 4, 4, 36, 5 };
-static const unsigned char salt[MAX_TESTS][40] =
+static const unsigned char salt_test_data[MAX_TESTS][40] =
{
"salt",
"salt",
@@ -358,13 +335,13 @@ static const unsigned char salt[MAX_TESTS][40] =
"sa\0lt",
};
-static const uint32_t it_cnt[MAX_TESTS] =
+static const uint32_t it_cnt_test_data[MAX_TESTS] =
{ 1, 2, 4096, 4096, 4096 };
-static const uint32_t key_len[MAX_TESTS] =
+static const uint32_t key_len_test_data[MAX_TESTS] =
{ 20, 20, 20, 25, 16 };
-static const unsigned char result_key[MAX_TESTS][32] =
+static const unsigned char result_key_test_data[MAX_TESTS][32] =
{
{ 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
@@ -410,10 +387,12 @@ int mbedtls_pkcs5_self_test( int verbose )
if( verbose != 0 )
mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i );
- ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i],
- slen[i], it_cnt[i], key_len[i], key );
+ ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password_test_data[i],
+ plen_test_data[i], salt_test_data[i],
+ slen_test_data[i], it_cnt_test_data[i],
+ key_len_test_data[i], key );
if( ret != 0 ||
- memcmp( result_key[i], key, key_len[i] ) != 0 )
+ memcmp( result_key_test_data[i], key, key_len_test_data[i] ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c
index 8471b51320..535ed70eb1 100644
--- a/thirdparty/mbedtls/library/pkparse.c
+++ b/thirdparty/mbedtls/library/pkparse.c
@@ -2,13 +2,7 @@
* Public Key layer for parsing key files and structures
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_PARSE_C)
@@ -56,6 +25,7 @@
#include "mbedtls/asn1.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -155,7 +125,7 @@ int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n )
int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
const char *path, const char *pwd )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -182,7 +152,7 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
*/
int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -213,11 +183,11 @@ int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path )
static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ( end - *p < 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
/* Tag may be either OID or SEQUENCE */
params->tag = **p;
@@ -227,21 +197,21 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
#endif
)
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
if( ( ret = mbedtls_asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
params->p = *p;
*p += params->len;
if( *p != end )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -268,7 +238,7 @@ static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
*/
static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = params->p;
const unsigned char * const end = params->p + params->len;
const unsigned char *end_field, *end_curve;
@@ -277,7 +247,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
/* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ver < 1 || ver > 3 )
return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
@@ -315,13 +285,13 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
/* Prime-p ::= INTEGER -- Field of size p. */
if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
grp->pbits = mbedtls_mpi_bitlen( &grp->P );
if( p != end_field )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* Curve ::= SEQUENCE {
@@ -345,7 +315,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -353,7 +323,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -363,14 +333,14 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
p += len;
if( p != end_curve )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* ECPoint ::= OCTET STRING
*/
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G,
( const unsigned char *) p, len ) ) != 0 )
@@ -396,7 +366,7 @@ static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_
* order INTEGER
*/
if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
grp->nbits = mbedtls_mpi_bitlen( &grp->N );
@@ -458,7 +428,7 @@ cleanup:
static int pk_group_id_from_specified( const mbedtls_asn1_buf *params,
mbedtls_ecp_group_id *grp_id )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group grp;
mbedtls_ecp_group_init( &grp );
@@ -485,7 +455,7 @@ cleanup:
*/
static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ecp_group_id grp_id;
if( params->tag == MBEDTLS_ASN1_OID )
@@ -525,7 +495,7 @@ static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *g
static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
mbedtls_ecp_keypair *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q,
(const unsigned char *) *p, end - *p ) ) == 0 )
@@ -553,20 +523,20 @@ static int pk_get_rsapubkey( unsigned char **p,
const unsigned char *end,
mbedtls_rsa_context *rsa )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Import N */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( ( ret = mbedtls_rsa_import_raw( rsa, *p, len, NULL, 0, NULL, 0,
NULL, 0, NULL, 0 ) ) != 0 )
@@ -576,7 +546,7 @@ static int pk_get_rsapubkey( unsigned char **p,
/* Import E */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( ( ret = mbedtls_rsa_import_raw( rsa, NULL, 0, NULL, 0, NULL, 0,
NULL, 0, *p, len ) ) != 0 )
@@ -591,8 +561,8 @@ static int pk_get_rsapubkey( unsigned char **p,
}
if( *p != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -608,13 +578,13 @@ static int pk_get_pk_alg( unsigned char **p,
const unsigned char *end,
mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_asn1_buf alg_oid;
memset( params, 0, sizeof(mbedtls_asn1_buf) );
if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_ALG, ret ) );
if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -640,7 +610,7 @@ static int pk_get_pk_alg( unsigned char **p,
int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
mbedtls_pk_context *pk )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
mbedtls_asn1_buf alg_params;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
@@ -654,7 +624,7 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = *p + len;
@@ -663,11 +633,11 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
return( ret );
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -692,8 +662,8 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG;
if( ret == 0 && *p != end )
- ret = MBEDTLS_ERR_PK_INVALID_PUBKEY +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
if( ret != 0 )
mbedtls_pk_free( pk );
@@ -764,14 +734,14 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
if( version != 0 )
@@ -861,8 +831,8 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
if( p != end )
{
- ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
}
cleanup:
@@ -873,7 +843,7 @@ cleanup:
{
/* Wrap error code if it's coming from a lower level */
if( ( ret & 0xff80 ) == 0 )
- ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret );
else
ret = MBEDTLS_ERR_PK_KEY_INVALID_FORMAT;
@@ -892,7 +862,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
const unsigned char *key,
size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int version, pubkey_done;
size_t len;
mbedtls_asn1_buf params;
@@ -913,24 +883,24 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( version != 1 )
return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
p += len;
@@ -954,7 +924,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
}
@@ -970,11 +940,11 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( p + len != end2 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
pubkey_done = 1;
@@ -991,7 +961,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
}
@@ -1000,7 +970,7 @@ static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck,
NULL, NULL ) ) != 0 )
{
mbedtls_ecp_keypair_free( eck );
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
@@ -1058,26 +1028,28 @@ static int pk_parse_key_pkcs8_unencrypted_der(
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( version != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_VERSION, ret ) );
if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
+ {
return( ret );
+ }
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( len < 1 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL )
return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG );
@@ -1160,16 +1132,16 @@ static int pk_parse_key_pkcs8_encrypted_der(
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
}
end = p + len;
if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT, ret ) );
buf = p;
@@ -1245,7 +1217,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
const unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_pk_info_t *pk_info;
#if defined(MBEDTLS_PEM_PARSE_C)
size_t len;
@@ -1460,7 +1432,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
const unsigned char *key, size_t keylen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
#if defined(MBEDTLS_RSA_C)
const mbedtls_pk_info_t *pk_info;
@@ -1551,7 +1523,8 @@ int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx,
return( ret );
}
mbedtls_pk_free( ctx );
- if( ret != ( MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
+ if( ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_PK_INVALID_PUBKEY,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) )
{
return( ret );
}
diff --git a/thirdparty/mbedtls/library/pkwrite.c b/thirdparty/mbedtls/library/pkwrite.c
index a770dfb93e..566153dd93 100644
--- a/thirdparty/mbedtls/library/pkwrite.c
+++ b/thirdparty/mbedtls/library/pkwrite.c
@@ -2,13 +2,7 @@
* Public Key layer for writing key files and structures
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PK_WRITE_C)
@@ -56,6 +25,7 @@
#include "mbedtls/asn1write.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,6 +44,10 @@
#include "mbedtls/pem.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -98,7 +72,7 @@
static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
mbedtls_rsa_context *rsa )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_mpi T;
@@ -137,7 +111,7 @@ end_of_export:
static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN];
@@ -165,7 +139,7 @@ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
static int pk_write_ec_param( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const char *oid;
size_t oid_len;
@@ -184,11 +158,11 @@ static int pk_write_ec_param( unsigned char **p, unsigned char *start,
static int pk_write_ec_private( unsigned char **p, unsigned char *start,
mbedtls_ecp_keypair *ec )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t byte_length = ( ec->grp.pbits + 7 ) / 8;
unsigned char tmp[MBEDTLS_ECP_MAX_BYTES];
- ret = mbedtls_mpi_write_binary( &ec->d, tmp, byte_length );
+ ret = mbedtls_ecp_write_key( ec, tmp, byte_length );
if( ret != 0 )
goto exit;
ret = mbedtls_asn1_write_octet_string( p, start, tmp, byte_length );
@@ -202,7 +176,7 @@ exit:
int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
const mbedtls_pk_context *key )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
PK_VALIDATE_RET( p != NULL );
@@ -220,6 +194,29 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) );
else
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_OPAQUE )
+ {
+ size_t buffer_size;
+ psa_key_id_t* key_id = (psa_key_id_t*) key->pk_ctx;
+
+ if ( *p < start )
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+
+ buffer_size = (size_t)( *p - start );
+ if ( psa_export_public_key( *key_id, start, buffer_size, &len )
+ != PSA_SUCCESS )
+ {
+ return( MBEDTLS_ERR_PK_BAD_INPUT_DATA );
+ }
+ else
+ {
+ *p -= len;
+ memmove( *p, start, len );
+ }
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
return( (int) len );
@@ -227,9 +224,10 @@ int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start,
int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *c;
size_t len = 0, par_len = 0, oid_len;
+ mbedtls_pk_type_t pk_type;
const char *oid;
PK_VALIDATE_RET( key != NULL );
@@ -255,18 +253,52 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
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_BIT_STRING ) );
- if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
- &oid, &oid_len ) ) != 0 )
- {
- return( ret );
- }
-
+ pk_type = mbedtls_pk_get_type( key );
#if defined(MBEDTLS_ECP_C)
- if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
+ if( pk_type == MBEDTLS_PK_ECKEY )
{
MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) );
}
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( pk_type == MBEDTLS_PK_OPAQUE )
+ {
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_key_type_t key_type;
+ psa_key_id_t key_id;
+ psa_ecc_family_t curve;
+ size_t bits;
+
+ key_id = *((psa_key_id_t*) key->pk_ctx );
+ if( PSA_SUCCESS != psa_get_key_attributes( key_id, &attributes ) )
+ return( MBEDTLS_ERR_PK_HW_ACCEL_FAILED );
+ key_type = psa_get_key_type( &attributes );
+ bits = psa_get_key_bits( &attributes );
+ psa_reset_key_attributes( &attributes );
+
+ curve = PSA_KEY_TYPE_ECC_GET_FAMILY( key_type );
+ if( curve == 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ ret = mbedtls_psa_get_ecc_oid_from_id( curve, bits, &oid, &oid_len );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
+
+ /* Write EC algorithm parameters; that's akin
+ * to pk_write_ec_param() above. */
+ MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_oid( &c, buf,
+ oid, oid_len ) );
+
+ /* The rest of the function works as for legacy EC contexts. */
+ pk_type = MBEDTLS_PK_ECKEY;
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = mbedtls_oid_get_oid_by_pk_alg( pk_type, &oid,
+ &oid_len ) ) != 0 )
+ {
+ return( ret );
+ }
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
par_len ) );
@@ -280,7 +312,7 @@ int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, si
int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *c;
size_t len = 0;
@@ -523,7 +555,7 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output_buf[PUB_DER_MAX_BYTES];
size_t olen = 0;
@@ -548,7 +580,7 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, si
int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char output_buf[PRV_DER_MAX_BYTES];
const char *begin, *end;
size_t olen = 0;
diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c
index c4c3fd332d..e742fde7cc 100644
--- a/thirdparty/mbedtls/library/platform.c
+++ b/thirdparty/mbedtls/library/platform.c
@@ -2,13 +2,7 @@
* Platform abstraction layer
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
/* The compile time configuration of memory allocation via the macros
* MBEDTLS_PLATFORM_{FREE/CALLOC}_MACRO takes precedence over the runtime
@@ -107,28 +77,15 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ),
!( defined(MBEDTLS_PLATFORM_CALLOC_MACRO) &&
defined(MBEDTLS_PLATFORM_FREE_MACRO) ) */
-#if defined(_WIN32)
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_SNPRINTF)
#include <stdarg.h>
int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
va_list argp;
- /* Avoid calling the invalid parameter handler by checking ourselves */
- if( s == NULL || n == 0 || fmt == NULL )
- return( -1 );
-
va_start( argp, fmt );
-#if defined(_TRUNCATE) && !defined(__MINGW32__)
- ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp );
-#else
- ret = _vsnprintf( s, n, fmt, argp );
- if( ret < 0 || (size_t) ret == n )
- {
- s[n-1] = '\0';
- ret = -1;
- }
-#endif
+ ret = mbedtls_vsnprintf( s, n, fmt, argp );
va_end( argp );
return( ret );
@@ -165,6 +122,62 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n,
}
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_HAS_NON_CONFORMING_VSNPRINTF)
+#include <stdarg.h>
+int mbedtls_platform_win32_vsnprintf( char *s, size_t n, const char *fmt, va_list arg )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Avoid calling the invalid parameter handler by checking ourselves */
+ if( s == NULL || n == 0 || fmt == NULL )
+ return( -1 );
+
+#if defined(_TRUNCATE)
+ ret = vsnprintf_s( s, n, _TRUNCATE, fmt, arg );
+#else
+ ret = vsnprintf( s, n, fmt, arg );
+ if( ret < 0 || (size_t) ret == n )
+ {
+ s[n-1] = '\0';
+ ret = -1;
+ }
+#endif
+
+ return( ret );
+}
+#endif
+
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+#if !defined(MBEDTLS_PLATFORM_STD_VSNPRINTF)
+/*
+ * Make dummy function to prevent NULL pointer dereferences
+ */
+static int platform_vsnprintf_uninit( char * s, size_t n,
+ const char * format, va_list arg )
+{
+ ((void) s);
+ ((void) n);
+ ((void) format);
+ ((void) arg);
+ return( -1 );
+}
+
+#define MBEDTLS_PLATFORM_STD_VSNPRINTF platform_vsnprintf_uninit
+#endif /* !MBEDTLS_PLATFORM_STD_VSNPRINTF */
+
+int (*mbedtls_vsnprintf)( char * s, size_t n,
+ const char * format,
+ va_list arg ) = MBEDTLS_PLATFORM_STD_VSNPRINTF;
+
+int mbedtls_platform_set_vsnprintf( int (*vsnprintf_func)( char * s, size_t n,
+ const char * format,
+ va_list arg ) )
+{
+ mbedtls_vsnprintf = vsnprintf_func;
+ return( 0 );
+}
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
+
#if defined(MBEDTLS_PLATFORM_PRINTF_ALT)
#if !defined(MBEDTLS_PLATFORM_STD_PRINTF)
/*
diff --git a/thirdparty/mbedtls/library/platform_util.c b/thirdparty/mbedtls/library/platform_util.c
index c8cd52d52a..98fe5deb2d 100644
--- a/thirdparty/mbedtls/library/platform_util.c
+++ b/thirdparty/mbedtls/library/platform_util.c
@@ -3,13 +3,7 @@
* library.
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,27 +16,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -53,11 +26,7 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/platform.h"
diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c
index 5b023f04e4..7375a0c572 100644
--- a/thirdparty/mbedtls/library/poly1305.c
+++ b/thirdparty/mbedtls/library/poly1305.c
@@ -4,13 +4,7 @@
* \brief Poly1305 authentication algorithm.
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,38 +17,14 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_POLY1305_C)
#include "mbedtls/poly1305.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -82,13 +52,6 @@
#define POLY1305_BLOCK_SIZE_BYTES ( 16U )
-#define BYTES_TO_U32_LE( data, offset ) \
- ( (uint32_t) (data)[offset] \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \
- | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \
- )
-
/*
* Our implementation is tuned for 32-bit platforms with a 64-bit multiplier.
* However we provided an alternative for platforms without such a multiplier.
@@ -159,10 +122,10 @@ static void poly1305_process( mbedtls_poly1305_context *ctx,
for( i = 0U; i < nblocks; i++ )
{
/* The input block is treated as a 128-bit little-endian integer */
- d0 = BYTES_TO_U32_LE( input, offset + 0 );
- d1 = BYTES_TO_U32_LE( input, offset + 4 );
- d2 = BYTES_TO_U32_LE( input, offset + 8 );
- d3 = BYTES_TO_U32_LE( input, offset + 12 );
+ d0 = MBEDTLS_GET_UINT32_LE( input, offset + 0 );
+ d1 = MBEDTLS_GET_UINT32_LE( input, offset + 4 );
+ d2 = MBEDTLS_GET_UINT32_LE( input, offset + 8 );
+ d3 = MBEDTLS_GET_UINT32_LE( input, offset + 12 );
/* Compute: acc += (padded) block as a 130-bit integer */
d0 += (uint64_t) acc0;
@@ -287,22 +250,10 @@ static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx,
acc3 += ctx->s[3] + (uint32_t) ( d >> 32U );
/* Compute MAC (128 least significant bits of the accumulator) */
- mac[ 0] = (unsigned char)( acc0 );
- mac[ 1] = (unsigned char)( acc0 >> 8 );
- mac[ 2] = (unsigned char)( acc0 >> 16 );
- mac[ 3] = (unsigned char)( acc0 >> 24 );
- mac[ 4] = (unsigned char)( acc1 );
- mac[ 5] = (unsigned char)( acc1 >> 8 );
- mac[ 6] = (unsigned char)( acc1 >> 16 );
- mac[ 7] = (unsigned char)( acc1 >> 24 );
- mac[ 8] = (unsigned char)( acc2 );
- mac[ 9] = (unsigned char)( acc2 >> 8 );
- mac[10] = (unsigned char)( acc2 >> 16 );
- mac[11] = (unsigned char)( acc2 >> 24 );
- mac[12] = (unsigned char)( acc3 );
- mac[13] = (unsigned char)( acc3 >> 8 );
- mac[14] = (unsigned char)( acc3 >> 16 );
- mac[15] = (unsigned char)( acc3 >> 24 );
+ MBEDTLS_PUT_UINT32_LE( acc0, mac, 0 );
+ MBEDTLS_PUT_UINT32_LE( acc1, mac, 4 );
+ MBEDTLS_PUT_UINT32_LE( acc2, mac, 8 );
+ MBEDTLS_PUT_UINT32_LE( acc3, mac, 12 );
}
void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
@@ -327,15 +278,15 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
POLY1305_VALIDATE_RET( key != NULL );
/* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */
- ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU;
- ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU;
- ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU;
- ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU;
+ ctx->r[0] = MBEDTLS_GET_UINT32_LE( key, 0 ) & 0x0FFFFFFFU;
+ ctx->r[1] = MBEDTLS_GET_UINT32_LE( key, 4 ) & 0x0FFFFFFCU;
+ ctx->r[2] = MBEDTLS_GET_UINT32_LE( key, 8 ) & 0x0FFFFFFCU;
+ ctx->r[3] = MBEDTLS_GET_UINT32_LE( key, 12 ) & 0x0FFFFFFCU;
- ctx->s[0] = BYTES_TO_U32_LE( key, 16 );
- ctx->s[1] = BYTES_TO_U32_LE( key, 20 );
- ctx->s[2] = BYTES_TO_U32_LE( key, 24 );
- ctx->s[3] = BYTES_TO_U32_LE( key, 28 );
+ ctx->s[0] = MBEDTLS_GET_UINT32_LE( key, 16 );
+ ctx->s[1] = MBEDTLS_GET_UINT32_LE( key, 20 );
+ ctx->s[2] = MBEDTLS_GET_UINT32_LE( key, 24 );
+ ctx->s[3] = MBEDTLS_GET_UINT32_LE( key, 28 );
/* Initial accumulator state */
ctx->acc[0] = 0U;
@@ -448,7 +399,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32],
unsigned char mac[16] )
{
mbedtls_poly1305_context ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
POLY1305_VALIDATE_RET( key != NULL );
POLY1305_VALIDATE_RET( mac != NULL );
POLY1305_VALIDATE_RET( ilen == 0 || input != NULL );
@@ -537,6 +488,9 @@ static const unsigned char test_mac[2][16] =
}
};
+/* Make sure no other definition is already present. */
+#undef ASSERT
+
#define ASSERT( cond, args ) \
do \
{ \
@@ -554,7 +508,7 @@ int mbedtls_poly1305_self_test( int verbose )
{
unsigned char mac[16];
unsigned i;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
for( i = 0U; i < 2U; i++ )
{
diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c
index c090c8f9d2..aed7322cff 100644
--- a/thirdparty/mbedtls/library/ripemd160.c
+++ b/thirdparty/mbedtls/library/ripemd160.c
@@ -2,13 +2,7 @@
* RIPE MD-160 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -50,16 +23,13 @@
* http://ehash.iaik.tugraz.at/wiki/RIPEMD-160
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RIPEMD160_C)
#include "mbedtls/ripemd160.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -74,29 +44,6 @@
#if !defined(MBEDTLS_RIPEMD160_ALT)
-/*
- * 32-bit integer manipulation macros (little endian)
- */
-#ifndef GET_UINT32_LE
-#define GET_UINT32_LE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
-}
-#endif
-
-#ifndef PUT_UINT32_LE
-#define PUT_UINT32_LE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
- (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
- (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
- (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
-}
-#endif
-
void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) );
@@ -152,22 +99,22 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx,
uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16];
} local;
- GET_UINT32_LE( local.X[ 0], data, 0 );
- GET_UINT32_LE( local.X[ 1], data, 4 );
- GET_UINT32_LE( local.X[ 2], data, 8 );
- GET_UINT32_LE( local.X[ 3], data, 12 );
- GET_UINT32_LE( local.X[ 4], data, 16 );
- GET_UINT32_LE( local.X[ 5], data, 20 );
- GET_UINT32_LE( local.X[ 6], data, 24 );
- GET_UINT32_LE( local.X[ 7], data, 28 );
- GET_UINT32_LE( local.X[ 8], data, 32 );
- GET_UINT32_LE( local.X[ 9], data, 36 );
- GET_UINT32_LE( local.X[10], data, 40 );
- GET_UINT32_LE( local.X[11], data, 44 );
- GET_UINT32_LE( local.X[12], data, 48 );
- GET_UINT32_LE( local.X[13], data, 52 );
- GET_UINT32_LE( local.X[14], data, 56 );
- GET_UINT32_LE( local.X[15], data, 60 );
+ local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
+ local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
+ local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
+ local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
+ local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
+ local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
+ local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
+ local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
+ local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
+ local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
+ local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
+ local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
+ local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
+ local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
+ local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
+ local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
local.A = local.Ap = ctx->state[0];
local.B = local.Bp = ctx->state[1];
@@ -353,7 +300,7 @@ int mbedtls_ripemd160_update_ret( mbedtls_ripemd160_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -421,7 +368,7 @@ static const unsigned char ripemd160_padding[64] =
int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t last, padn;
uint32_t high, low;
unsigned char msglen[8];
@@ -430,8 +377,8 @@ int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_LE( low, msglen, 0 );
- PUT_UINT32_LE( high, msglen, 4 );
+ MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
+ MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
last = ctx->total[0] & 0x3F;
padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
@@ -444,11 +391,11 @@ int mbedtls_ripemd160_finish_ret( mbedtls_ripemd160_context *ctx,
if( ret != 0 )
return( ret );
- PUT_UINT32_LE( ctx->state[0], output, 0 );
- PUT_UINT32_LE( ctx->state[1], output, 4 );
- PUT_UINT32_LE( ctx->state[2], output, 8 );
- PUT_UINT32_LE( ctx->state[3], output, 12 );
- PUT_UINT32_LE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_LE( ctx->state[4], output, 16 );
return( 0 );
}
@@ -470,7 +417,7 @@ int mbedtls_ripemd160_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ripemd160_context ctx;
mbedtls_ripemd160_init( &ctx );
diff --git a/thirdparty/mbedtls/library/rsa.c b/thirdparty/mbedtls/library/rsa.c
index 47d784c1ba..8a5d40ff1e 100644
--- a/thirdparty/mbedtls/library/rsa.c
+++ b/thirdparty/mbedtls/library/rsa.c
@@ -2,13 +2,7 @@
* The RSA public-key cryptosystem
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -62,11 +35,7 @@
*
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RSA_C)
@@ -74,6 +43,9 @@
#include "mbedtls/rsa_internal.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -102,28 +74,12 @@
#define RSA_VALIDATE( cond ) \
MBEDTLS_INTERNAL_VALIDATE( cond )
-#if defined(MBEDTLS_PKCS1_V15)
-/* constant-time buffer comparison */
-static inline int mbedtls_safer_memcmp( const void *a, const void *b, size_t n )
-{
- size_t i;
- const unsigned char *A = (const unsigned char *) a;
- const unsigned char *B = (const unsigned char *) b;
- unsigned char diff = 0;
-
- for( i = 0; i < n; i++ )
- diff |= A[i] ^ B[i];
-
- return( diff );
-}
-#endif /* MBEDTLS_PKCS1_V15 */
-
int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
const mbedtls_mpi *N,
const mbedtls_mpi *P, const mbedtls_mpi *Q,
const mbedtls_mpi *D, const mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( ctx != NULL );
if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
@@ -132,7 +88,7 @@ int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
if( N != NULL )
@@ -172,7 +128,7 @@ int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
cleanup:
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
return( 0 );
}
@@ -323,7 +279,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
&ctx->Q ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
ctx->len = mbedtls_mpi_size( &ctx->N );
@@ -338,7 +294,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_primes( &ctx->N, &ctx->E, &ctx->D,
&ctx->P, &ctx->Q );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
else if( d_missing )
@@ -348,7 +304,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
&ctx->E,
&ctx->D ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
}
@@ -363,7 +319,7 @@ int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
&ctx->DP, &ctx->DQ, &ctx->QP );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif /* MBEDTLS_RSA_NO_CRT */
@@ -426,7 +382,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
mbedtls_mpi *D, mbedtls_mpi *E )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -470,7 +426,7 @@ int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
int is_priv;
RSA_VALIDATE_RET( ctx != NULL );
@@ -491,13 +447,13 @@ int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#else
if( ( ret = mbedtls_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
DP, DQ, QP ) ) != 0 )
{
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_BAD_INPUT_DATA, ret ) );
}
#endif
@@ -564,7 +520,7 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
void *p_rng,
unsigned int nbits, int exponent )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_mpi H, G, L;
int prime_quality = 0;
RSA_VALIDATE_RET( ctx != NULL );
@@ -665,8 +621,9 @@ cleanup:
if( ret != 0 )
{
mbedtls_rsa_free( ctx );
+
if( ( -ret & ~0x7f ) == 0 )
- ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_KEY_GEN_FAILED, ret );
return( ret );
}
@@ -761,7 +718,7 @@ int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
mbedtls_mpi T;
RSA_VALIDATE_RET( ctx != NULL );
@@ -799,7 +756,7 @@ cleanup:
mbedtls_mpi_free( &T );
if( ret != 0 )
- return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PUBLIC_FAILED, ret ) );
return( 0 );
}
@@ -899,7 +856,7 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
const unsigned char *input,
unsigned char *output )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
/* Temporary holding the result */
@@ -1115,7 +1072,7 @@ cleanup:
mbedtls_mpi_free( &I );
if( ret != 0 && ret >= -0x007f )
- return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret ) );
return( ret );
}
@@ -1192,7 +1149,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
unsigned int hlen;
const mbedtls_md_info_t *md_info;
@@ -1202,7 +1159,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
RSA_VALIDATE_RET( label_len == 0 || label != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
@@ -1228,7 +1185,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
/* Generate a random octet string seed */
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p += hlen;
@@ -1238,7 +1195,8 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
p += hlen;
p += olen - 2 * hlen - 2 - ilen;
*p++ = 1;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
mbedtls_md_init( &md_ctx );
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 )
@@ -1278,14 +1236,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
unsigned char *output )
{
size_t nb_pad, olen;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = output;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1316,7 +1274,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
/* Check if RNG failed to generate data */
if( rng_dl == 0 || ret != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
p++;
}
@@ -1330,7 +1288,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
}
*p++ = 0;
- memcpy( p, input, ilen );
+ if( ilen != 0 )
+ memcpy( p, input, ilen );
return( ( mode == MBEDTLS_RSA_PUBLIC )
? mbedtls_rsa_public( ctx, output, output )
@@ -1352,7 +1311,7 @@ int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
mode == MBEDTLS_RSA_PUBLIC );
RSA_VALIDATE_RET( output != NULL );
- RSA_VALIDATE_RET( input != NULL );
+ RSA_VALIDATE_RET( ilen == 0 || input != NULL );
switch( ctx->padding )
{
@@ -1387,7 +1346,7 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
unsigned char *output,
size_t output_max_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t ilen, i, pad_len;
unsigned char *p, bad, pad_done;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
@@ -1508,7 +1467,8 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
}
*olen = ilen - (p - buf);
- memcpy( output, p, *olen );
+ if( *olen != 0 )
+ memcpy( output, p, *olen );
ret = 0;
cleanup:
@@ -1520,126 +1480,21 @@ cleanup:
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
-/** Turn zero-or-nonzero into zero-or-all-bits-one, without branches.
- *
- * \param value The value to analyze.
- * \return Zero if \p value is zero, otherwise all-bits-one.
- */
-static unsigned all_or_nothing_int( unsigned value )
-{
- /* MSVC has a warning about unary minus on unsigned, 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
- return( - ( ( value | - value ) >> ( sizeof( value ) * 8 - 1 ) ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
-}
-
-/** Check whether a size is out of bounds, without branches.
- *
- * This is equivalent to `size > max`, but is likely to be compiled to
- * to code using bitwise operation rather than a branch.
- *
- * \param size Size to check.
- * \param max Maximum desired value for \p size.
- * \return \c 0 if `size <= max`.
- * \return \c 1 if `size > max`.
- */
-static unsigned size_greater_than( size_t size, size_t max )
-{
- /* Return the sign bit (1 for negative) of (max - size). */
- return( ( max - size ) >> ( sizeof( size_t ) * 8 - 1 ) );
-}
-
-/** Choose between two integer values, without branches.
- *
- * This is equivalent to `cond ? if1 : if0`, but is likely to be compiled
- * to code using bitwise operation rather than a branch.
- *
- * \param cond Condition to test.
- * \param if1 Value to use if \p cond is nonzero.
- * \param if0 Value to use if \p cond is zero.
- * \return \c if1 if \p cond is nonzero, otherwise \c if0.
- */
-static unsigned if_int( unsigned cond, unsigned if1, unsigned if0 )
-{
- unsigned mask = all_or_nothing_int( cond );
- return( ( mask & if1 ) | (~mask & if0 ) );
-}
-
-/** Shift some data towards the left inside a buffer without leaking
- * the length of the data through side channels.
- *
- * `mem_move_to_left(start, total, offset)` is functionally equivalent to
- * ```
- * memmove(start, start + offset, total - offset);
- * memset(start + offset, 0, total - offset);
- * ```
- * but it strives to use a memory access pattern (and thus total timing)
- * that does not depend on \p offset. This timing independence comes at
- * the expense of performance.
- *
- * \param start Pointer to the start of the buffer.
- * \param total Total size of the buffer.
- * \param offset Offset from which to copy \p total - \p offset bytes.
- */
-static void mem_move_to_left( void *start,
- size_t total,
- size_t offset )
-{
- volatile unsigned char *buf = start;
- size_t i, n;
- if( total == 0 )
- return;
- for( i = 0; i < total; i++ )
- {
- unsigned no_op = size_greater_than( total - offset, i );
- /* The first `total - offset` passes are a no-op. The last
- * `offset` passes shift the data one byte to the left and
- * zero out the last byte. */
- for( n = 0; n < total - 1; n++ )
- {
- unsigned char current = buf[n];
- unsigned char next = buf[n+1];
- buf[n] = if_int( no_op, current, next );
- }
- buf[total-1] = if_int( no_op, buf[total-1], 0 );
- }
-}
-
/*
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
*/
int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
- int mode, size_t *olen,
+ int mode,
+ size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len )
{
- int ret;
- size_t ilen, i, plaintext_max_size;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t ilen;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
- /* The following variables take sensitive values: their value must
- * not leak into the observable behavior of the function other than
- * the designated outputs (output, olen, return value). Otherwise
- * this would open the execution of the function to
- * side-channel-based variants of the Bleichenbacher padding oracle
- * attack. Potential side channels include overall timing, memory
- * access patterns (especially visible to an adversary who has access
- * to a shared memory cache), and branches (especially visible to
- * an adversary who has access to a shared code cache or to a shared
- * branch predictor). */
- size_t pad_count = 0;
- unsigned bad = 0;
- unsigned char pad_done = 0;
- size_t plaintext_size = 0;
- unsigned output_too_large;
RSA_VALIDATE_RET( ctx != NULL );
RSA_VALIDATE_RET( mode == MBEDTLS_RSA_PRIVATE ||
@@ -1649,9 +1504,6 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
RSA_VALIDATE_RET( olen != NULL );
ilen = ctx->len;
- plaintext_max_size = ( output_max_len > ilen - 11 ?
- ilen - 11 :
- output_max_len );
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@@ -1666,109 +1518,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
if( ret != 0 )
goto cleanup;
- /* Check and get padding length in constant time and constant
- * memory trace. The first byte must be 0. */
- bad |= buf[0];
-
- if( mode == MBEDTLS_RSA_PRIVATE )
- {
- /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
- * where PS must be at least 8 nonzero bytes. */
- bad |= buf[1] ^ MBEDTLS_RSA_CRYPT;
-
- /* Read the whole buffer. Set pad_done to nonzero if we find
- * the 0x00 byte and remember the padding length in pad_count. */
- for( i = 2; i < ilen; i++ )
- {
- pad_done |= ((buf[i] | (unsigned char)-buf[i]) >> 7) ^ 1;
- pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
- }
- }
- else
- {
- /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
- * where PS must be at least 8 bytes with the value 0xFF. */
- bad |= buf[1] ^ MBEDTLS_RSA_SIGN;
-
- /* Read the whole buffer. Set pad_done to nonzero if we find
- * the 0x00 byte and remember the padding length in pad_count.
- * If there's a non-0xff byte in the padding, the padding is bad. */
- for( i = 2; i < ilen; i++ )
- {
- pad_done |= if_int( buf[i], 0, 1 );
- pad_count += if_int( pad_done, 0, 1 );
- bad |= if_int( pad_done, 0, buf[i] ^ 0xFF );
- }
- }
-
- /* If pad_done is still zero, there's no data, only unfinished padding. */
- bad |= if_int( pad_done, 0, 1 );
-
- /* There must be at least 8 bytes of padding. */
- bad |= size_greater_than( 8, pad_count );
-
- /* If the padding is valid, set plaintext_size to the number of
- * remaining bytes after stripping the padding. If the padding
- * is invalid, avoid leaking this fact through the size of the
- * output: use the maximum message size that fits in the output
- * buffer. Do it without branches to avoid leaking the padding
- * validity through timing. RSA keys are small enough that all the
- * size_t values involved fit in unsigned int. */
- plaintext_size = if_int( bad,
- (unsigned) plaintext_max_size,
- (unsigned) ( ilen - pad_count - 3 ) );
-
- /* Set output_too_large to 0 if the plaintext fits in the output
- * buffer and to 1 otherwise. */
- output_too_large = size_greater_than( plaintext_size,
- plaintext_max_size );
-
- /* Set ret without branches to avoid timing attacks. Return:
- * - INVALID_PADDING if the padding is bad (bad != 0).
- * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
- * plaintext does not fit in the output buffer.
- * - 0 if the padding is correct. */
- ret = - (int) if_int( bad, - MBEDTLS_ERR_RSA_INVALID_PADDING,
- if_int( output_too_large, - MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
- 0 ) );
-
- /* If the padding is bad or the plaintext is too large, zero the
- * data that we're about to copy to the output buffer.
- * We need to copy the same amount of data
- * from the same buffer whether the padding is good or not to
- * avoid leaking the padding validity through overall timing or
- * through memory or cache access patterns. */
- bad = all_or_nothing_int( bad | output_too_large );
- for( i = 11; i < ilen; i++ )
- buf[i] &= ~bad;
-
- /* If the plaintext is too large, truncate it to the buffer size.
- * Copy anyway to avoid revealing the length through timing, because
- * revealing the length is as bad as revealing the padding validity
- * for a Bleichenbacher attack. */
- plaintext_size = if_int( output_too_large,
- (unsigned) plaintext_max_size,
- (unsigned) plaintext_size );
-
- /* Move the plaintext to the leftmost position where it can start in
- * the working buffer, i.e. make it start plaintext_max_size from
- * the end of the buffer. Do this with a memory access trace that
- * does not depend on the plaintext size. After this move, the
- * starting location of the plaintext is no longer sensitive
- * information. */
- mem_move_to_left( buf + ilen - plaintext_max_size,
- plaintext_max_size,
- plaintext_max_size - plaintext_size );
-
- /* Finally copy the decrypted plaintext plus trailing zeros
- * into the output buffer. */
- memcpy( output, buf + ilen - plaintext_max_size, plaintext_max_size );
-
- /* Report the amount of data we copied to the output buffer. In case
- * of errors (bad padding or output too large), the value of *olen
- * when this function returns is not specified. Making it equivalent
- * to the good case limits the risks of leaking the padding validity. */
- *olen = plaintext_size;
+ ret = mbedtls_ct_rsaes_pkcs1_v15_unpadding( mode, buf, ilen,
+ output, output_max_len, olen );
cleanup:
mbedtls_platform_zeroize( buf, sizeof( buf ) );
@@ -1816,23 +1567,21 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
}
#if defined(MBEDTLS_PKCS1_V21)
-/*
- * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
- */
-int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+static int rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
+ int saltlen,
unsigned char *sig )
{
size_t olen;
unsigned char *p = sig;
- unsigned char salt[MBEDTLS_MD_MAX_SIZE];
+ unsigned char *salt = NULL;
size_t slen, min_slen, hlen, offset = 0;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t msb;
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
@@ -1868,31 +1617,44 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
hlen = mbedtls_md_get_size( md_info );
- /* Calculate the largest possible salt length. Normally this is the hash
- * length, which is the maximum length the salt can have. If there is not
- * enough room, use the maximum salt length that fits. The constraint is
- * that the hash length plus the salt length plus 2 bytes must be at most
- * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
- * (PKCS#1 v2.2) §9.1.1 step 3. */
- min_slen = hlen - 2;
- if( olen < hlen + min_slen + 2 )
+ if (saltlen == MBEDTLS_RSA_SALT_LEN_ANY)
+ {
+ /* Calculate the largest possible salt length, up to the hash size.
+ * Normally this is the hash length, which is the maximum salt length
+ * according to FIPS 185-4 §5.5 (e) and common practice. If there is not
+ * enough room, use the maximum salt length that fits. The constraint is
+ * that the hash length plus the salt length plus 2 bytes must be at most
+ * the key length. This complies with FIPS 186-4 §5.5 (e) and RFC 8017
+ * (PKCS#1 v2.2) §9.1.1 step 3. */
+ min_slen = hlen - 2;
+ if( olen < hlen + min_slen + 2 )
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ else if( olen >= hlen + hlen + 2 )
+ slen = hlen;
+ else
+ slen = olen - hlen - 2;
+ }
+ else if ( (saltlen < 0) || (saltlen + hlen + 2 > olen) )
+ {
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
- else if( olen >= hlen + hlen + 2 )
- slen = hlen;
+ }
else
- slen = olen - hlen - 2;
+ {
+ slen = (size_t) saltlen;
+ }
memset( sig, 0, olen );
- /* Generate salt of length slen */
- if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
- return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
-
/* Note: EMSA-PSS encoding is over the length of N - 1 bits */
msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
p += olen - hlen - slen - 2;
*p++ = 0x01;
- memcpy( p, salt, slen );
+
+ /* Generate salt of length slen in place in the encoded message */
+ salt = p;
+ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_RSA_RNG_FAILED, ret ) );
+
p += slen;
mbedtls_md_init( &md_ctx );
@@ -1926,8 +1688,6 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
p += hlen;
*p++ = 0xBC;
- mbedtls_platform_zeroize( salt, sizeof( salt ) );
-
exit:
mbedtls_md_free( &md_ctx );
@@ -1938,6 +1698,40 @@ exit:
? mbedtls_rsa_public( ctx, sig, sig )
: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) );
}
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function with
+ * the option to pass in the salt length.
+ */
+int mbedtls_rsa_rsassa_pss_sign_ext( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ int saltlen,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, md_alg,
+ hashlen, hash, saltlen, sig );
+}
+
+
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng,
+ int mode,
+ mbedtls_md_type_t md_alg,
+ unsigned int hashlen,
+ const unsigned char *hash,
+ unsigned char *sig )
+{
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+ hashlen, hash, MBEDTLS_RSA_SALT_LEN_ANY, sig );
+}
#endif /* MBEDTLS_PKCS1_V21 */
#if defined(MBEDTLS_PKCS1_V15)
@@ -2087,7 +1881,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
const unsigned char *hash,
unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *sig_try = NULL, *verif = NULL;
RSA_VALIDATE_RET( ctx != NULL );
@@ -2139,7 +1933,7 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
- if( mbedtls_safer_memcmp( verif, sig, ctx->len ) != 0 )
+ if( mbedtls_ct_memcmp( verif, sig, ctx->len ) != 0 )
{
ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
goto cleanup;
@@ -2213,7 +2007,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
int expected_salt_len,
const unsigned char *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t siglen;
unsigned char *p;
unsigned char *hash_start;
@@ -2441,8 +2235,8 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
* Compare
*/
- if( ( ret = mbedtls_safer_memcmp( encoded, encoded_expected,
- sig_len ) ) != 0 )
+ if( ( ret = mbedtls_ct_memcmp( encoded, encoded_expected,
+ sig_len ) ) != 0 )
{
ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
goto cleanup;
@@ -2510,7 +2304,7 @@ int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
*/
int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
RSA_VALIDATE_RET( dst != NULL );
RSA_VALIDATE_RET( src != NULL );
diff --git a/thirdparty/mbedtls/library/rsa_internal.c b/thirdparty/mbedtls/library/rsa_internal.c
index 4d94ca685a..d6ba97a14b 100644
--- a/thirdparty/mbedtls/library/rsa_internal.c
+++ b/thirdparty/mbedtls/library/rsa_internal.c
@@ -2,13 +2,7 @@
* Helper functions for the RSA module
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -22,34 +16,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
- *
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_RSA_C)
diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c
index e99a5e8635..0a5edafaff 100644
--- a/thirdparty/mbedtls/library/sha1.c
+++ b/thirdparty/mbedtls/library/sha1.c
@@ -2,13 +2,7 @@
* FIPS-180-1 compliant SHA-1 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-1 standard was published by NIST in 1993.
@@ -49,16 +22,13 @@
* http://www.itl.nist.gov/fipspubs/fip180-1.htm
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -78,29 +48,6 @@
#if !defined(MBEDTLS_SHA1_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
{
SHA1_VALIDATE( ctx != NULL );
@@ -163,22 +110,22 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx,
SHA1_VALIDATE_RET( ctx != NULL );
SHA1_VALIDATE_RET( (const unsigned char *)data != NULL );
- GET_UINT32_BE( local.W[ 0], data, 0 );
- GET_UINT32_BE( local.W[ 1], data, 4 );
- GET_UINT32_BE( local.W[ 2], data, 8 );
- GET_UINT32_BE( local.W[ 3], data, 12 );
- GET_UINT32_BE( local.W[ 4], data, 16 );
- GET_UINT32_BE( local.W[ 5], data, 20 );
- GET_UINT32_BE( local.W[ 6], data, 24 );
- GET_UINT32_BE( local.W[ 7], data, 28 );
- GET_UINT32_BE( local.W[ 8], data, 32 );
- GET_UINT32_BE( local.W[ 9], data, 36 );
- GET_UINT32_BE( local.W[10], data, 40 );
- GET_UINT32_BE( local.W[11], data, 44 );
- GET_UINT32_BE( local.W[12], data, 48 );
- GET_UINT32_BE( local.W[13], data, 52 );
- GET_UINT32_BE( local.W[14], data, 56 );
- GET_UINT32_BE( local.W[15], data, 60 );
+ local.W[ 0] = MBEDTLS_GET_UINT32_BE( data, 0 );
+ local.W[ 1] = MBEDTLS_GET_UINT32_BE( data, 4 );
+ local.W[ 2] = MBEDTLS_GET_UINT32_BE( data, 8 );
+ local.W[ 3] = MBEDTLS_GET_UINT32_BE( data, 12 );
+ local.W[ 4] = MBEDTLS_GET_UINT32_BE( data, 16 );
+ local.W[ 5] = MBEDTLS_GET_UINT32_BE( data, 20 );
+ local.W[ 6] = MBEDTLS_GET_UINT32_BE( data, 24 );
+ local.W[ 7] = MBEDTLS_GET_UINT32_BE( data, 28 );
+ local.W[ 8] = MBEDTLS_GET_UINT32_BE( data, 32 );
+ local.W[ 9] = MBEDTLS_GET_UINT32_BE( data, 36 );
+ local.W[10] = MBEDTLS_GET_UINT32_BE( data, 40 );
+ local.W[11] = MBEDTLS_GET_UINT32_BE( data, 44 );
+ local.W[12] = MBEDTLS_GET_UINT32_BE( data, 48 );
+ local.W[13] = MBEDTLS_GET_UINT32_BE( data, 52 );
+ local.W[14] = MBEDTLS_GET_UINT32_BE( data, 56 );
+ local.W[15] = MBEDTLS_GET_UINT32_BE( data, 60 );
#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
@@ -340,7 +287,7 @@ int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -401,7 +348,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx,
int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -438,8 +385,8 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, ctx->buffer, 56 );
- PUT_UINT32_BE( low, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -447,11 +394,11 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
return( 0 );
}
@@ -473,7 +420,7 @@ int mbedtls_sha1_ret( const unsigned char *input,
size_t ilen,
unsigned char output[20] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha1_context ctx;
SHA1_VALIDATE_RET( ilen == 0 || input != NULL );
diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c
index 75a8f8a2b2..db675efd1b 100644
--- a/thirdparty/mbedtls/library/sha256.c
+++ b/thirdparty/mbedtls/library/sha256.c
@@ -2,13 +2,7 @@
* FIPS-180-2 compliant SHA-256 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-256 Secure Hash Standard was published by NIST in 2002.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#include <string.h>
@@ -80,29 +50,6 @@
#if !defined(MBEDTLS_SHA256_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-do { \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-} while( 0 )
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-do { \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-} while( 0 )
-#endif
-
void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
{
SHA256_VALIDATE( ctx != NULL );
@@ -244,7 +191,7 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
for( i = 0; i < 64; i++ )
{
if( i < 16 )
- GET_UINT32_BE( local.W[i], data, 4 * i );
+ local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
else
R( i );
@@ -259,7 +206,7 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
}
#else /* MBEDTLS_SHA256_SMALLER */
for( i = 0; i < 16; i++ )
- GET_UINT32_BE( local.W[i], data, 4 * i );
+ local.W[i] = MBEDTLS_GET_UINT32_BE( data, 4 * i );
for( i = 0; i < 16; i += 8 )
{
@@ -327,7 +274,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
uint32_t left;
@@ -388,7 +335,7 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx,
int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
unsigned char output[32] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t used;
uint32_t high, low;
@@ -425,8 +372,8 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT32_BE( high, ctx->buffer, 56 );
- PUT_UINT32_BE( low, ctx->buffer, 60 );
+ MBEDTLS_PUT_UINT32_BE( high, ctx->buffer, 56 );
+ MBEDTLS_PUT_UINT32_BE( low, ctx->buffer, 60 );
if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -434,16 +381,16 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
/*
* Output final state
*/
- PUT_UINT32_BE( ctx->state[0], output, 0 );
- PUT_UINT32_BE( ctx->state[1], output, 4 );
- PUT_UINT32_BE( ctx->state[2], output, 8 );
- PUT_UINT32_BE( ctx->state[3], output, 12 );
- PUT_UINT32_BE( ctx->state[4], output, 16 );
- PUT_UINT32_BE( ctx->state[5], output, 20 );
- PUT_UINT32_BE( ctx->state[6], output, 24 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[0], output, 0 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[1], output, 4 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[2], output, 8 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[3], output, 12 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[4], output, 16 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[5], output, 20 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[6], output, 24 );
if( ctx->is224 == 0 )
- PUT_UINT32_BE( ctx->state[7], output, 28 );
+ MBEDTLS_PUT_UINT32_BE( ctx->state[7], output, 28 );
return( 0 );
}
@@ -466,7 +413,7 @@ int mbedtls_sha256_ret( const unsigned char *input,
unsigned char output[32],
int is224 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha256_context ctx;
SHA256_VALIDATE_RET( is224 == 0 || is224 == 1 );
diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c
index 3347afe5ff..02a135ca92 100644
--- a/thirdparty/mbedtls/library/sha512.c
+++ b/thirdparty/mbedtls/library/sha512.c
@@ -2,13 +2,7 @@
* FIPS-180-2 compliant SHA-384/512 implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SHA-512 Secure Hash Standard was published by NIST in 2002.
@@ -49,16 +22,13 @@
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/error.h"
#if defined(_MSC_VER) || defined(__WATCOMC__)
#define UL64(x) x##ui64
@@ -86,36 +56,14 @@
#if !defined(MBEDTLS_SHA512_ALT)
-/*
- * 64-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT64_BE
-#define GET_UINT64_BE(n,b,i) \
-{ \
- (n) = ( (uint64_t) (b)[(i) ] << 56 ) \
- | ( (uint64_t) (b)[(i) + 1] << 48 ) \
- | ( (uint64_t) (b)[(i) + 2] << 40 ) \
- | ( (uint64_t) (b)[(i) + 3] << 32 ) \
- | ( (uint64_t) (b)[(i) + 4] << 24 ) \
- | ( (uint64_t) (b)[(i) + 5] << 16 ) \
- | ( (uint64_t) (b)[(i) + 6] << 8 ) \
- | ( (uint64_t) (b)[(i) + 7] ); \
-}
-#endif /* GET_UINT64_BE */
-
-#ifndef PUT_UINT64_BE
-#define PUT_UINT64_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \
- (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 7] = (unsigned char) ( (n) ); \
+#if defined(MBEDTLS_SHA512_SMALLER)
+static void sha512_put_uint64_be( uint64_t n, unsigned char *b, uint8_t i )
+{
+ MBEDTLS_PUT_UINT64_BE(n, b, i);
}
-#endif /* PUT_UINT64_BE */
+#else
+#define sha512_put_uint64_be MBEDTLS_PUT_UINT64_BE
+#endif /* MBEDTLS_SHA512_SMALLER */
void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{
@@ -147,7 +95,11 @@ void mbedtls_sha512_clone( mbedtls_sha512_context *dst,
int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
{
SHA512_VALIDATE_RET( ctx != NULL );
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+#else
+ SHA512_VALIDATE_RET( is384 == 0 );
+#endif
ctx->total[0] = 0;
ctx->total[1] = 0;
@@ -166,6 +118,9 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
}
else
{
+#if defined(MBEDTLS_SHA512_NO_SHA384)
+ return( MBEDTLS_ERR_SHA512_BAD_INPUT_DATA );
+#else
/* SHA-384 */
ctx->state[0] = UL64(0xCBBB9D5DC1059ED8);
ctx->state[1] = UL64(0x629A292A367CD507);
@@ -175,9 +130,12 @@ int mbedtls_sha512_starts_ret( mbedtls_sha512_context *ctx, int is384 )
ctx->state[5] = UL64(0x8EB44A8768581511);
ctx->state[6] = UL64(0xDB0C2E0D64F98FA7);
ctx->state[7] = UL64(0x47B5481DBEFA4FA4);
+#endif /* MBEDTLS_SHA512_NO_SHA384 */
}
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
ctx->is384 = is384;
+#endif
return( 0 );
}
@@ -246,7 +204,7 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
struct
{
uint64_t temp1, temp2, W[80];
- uint64_t A, B, C, D, E, F, G, H;
+ uint64_t A[8];
} local;
SHA512_VALIDATE_RET( ctx != NULL );
@@ -272,56 +230,68 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx,
(d) += local.temp1; (h) = local.temp1 + local.temp2; \
} while( 0 )
+ for( i = 0; i < 8; i++ )
+ local.A[i] = ctx->state[i];
+
+#if defined(MBEDTLS_SHA512_SMALLER)
+ for( i = 0; i < 80; i++ )
+ {
+ if( i < 16 )
+ {
+ local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
+ }
+ else
+ {
+ local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
+ S0(local.W[i - 15]) + local.W[i - 16];
+ }
+
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] );
+
+ local.temp1 = local.A[7]; local.A[7] = local.A[6];
+ local.A[6] = local.A[5]; local.A[5] = local.A[4];
+ local.A[4] = local.A[3]; local.A[3] = local.A[2];
+ local.A[2] = local.A[1]; local.A[1] = local.A[0];
+ local.A[0] = local.temp1;
+ }
+#else /* MBEDTLS_SHA512_SMALLER */
for( i = 0; i < 16; i++ )
{
- GET_UINT64_BE( local.W[i], data, i << 3 );
+ local.W[i] = MBEDTLS_GET_UINT64_BE( data, i << 3 );
}
for( ; i < 80; i++ )
{
local.W[i] = S1(local.W[i - 2]) + local.W[i - 7] +
- S0(local.W[i - 15]) + local.W[i - 16];
+ S0(local.W[i - 15]) + local.W[i - 16];
}
- local.A = ctx->state[0];
- local.B = ctx->state[1];
- local.C = ctx->state[2];
- local.D = ctx->state[3];
- local.E = ctx->state[4];
- local.F = ctx->state[5];
- local.G = ctx->state[6];
- local.H = ctx->state[7];
i = 0;
-
do
{
- P( local.A, local.B, local.C, local.D, local.E,
- local.F, local.G, local.H, local.W[i], K[i] ); i++;
- P( local.H, local.A, local.B, local.C, local.D,
- local.E, local.F, local.G, local.W[i], K[i] ); i++;
- P( local.G, local.H, local.A, local.B, local.C,
- local.D, local.E, local.F, local.W[i], K[i] ); i++;
- P( local.F, local.G, local.H, local.A, local.B,
- local.C, local.D, local.E, local.W[i], K[i] ); i++;
- P( local.E, local.F, local.G, local.H, local.A,
- local.B, local.C, local.D, local.W[i], K[i] ); i++;
- P( local.D, local.E, local.F, local.G, local.H,
- local.A, local.B, local.C, local.W[i], K[i] ); i++;
- P( local.C, local.D, local.E, local.F, local.G,
- local.H, local.A, local.B, local.W[i], K[i] ); i++;
- P( local.B, local.C, local.D, local.E, local.F,
- local.G, local.H, local.A, local.W[i], K[i] ); i++;
+ P( local.A[0], local.A[1], local.A[2], local.A[3], local.A[4],
+ local.A[5], local.A[6], local.A[7], local.W[i], K[i] ); i++;
+ P( local.A[7], local.A[0], local.A[1], local.A[2], local.A[3],
+ local.A[4], local.A[5], local.A[6], local.W[i], K[i] ); i++;
+ P( local.A[6], local.A[7], local.A[0], local.A[1], local.A[2],
+ local.A[3], local.A[4], local.A[5], local.W[i], K[i] ); i++;
+ P( local.A[5], local.A[6], local.A[7], local.A[0], local.A[1],
+ local.A[2], local.A[3], local.A[4], local.W[i], K[i] ); i++;
+ P( local.A[4], local.A[5], local.A[6], local.A[7], local.A[0],
+ local.A[1], local.A[2], local.A[3], local.W[i], K[i] ); i++;
+ P( local.A[3], local.A[4], local.A[5], local.A[6], local.A[7],
+ local.A[0], local.A[1], local.A[2], local.W[i], K[i] ); i++;
+ P( local.A[2], local.A[3], local.A[4], local.A[5], local.A[6],
+ local.A[7], local.A[0], local.A[1], local.W[i], K[i] ); i++;
+ P( local.A[1], local.A[2], local.A[3], local.A[4], local.A[5],
+ local.A[6], local.A[7], local.A[0], local.W[i], K[i] ); i++;
}
while( i < 80 );
+#endif /* MBEDTLS_SHA512_SMALLER */
- ctx->state[0] += local.A;
- ctx->state[1] += local.B;
- ctx->state[2] += local.C;
- ctx->state[3] += local.D;
- ctx->state[4] += local.E;
- ctx->state[5] += local.F;
- ctx->state[6] += local.G;
- ctx->state[7] += local.H;
+ for( i = 0; i < 8; i++ )
+ ctx->state[i] += local.A[i];
/* Zeroise buffers and variables to clear sensitive data from memory. */
mbedtls_platform_zeroize( &local, sizeof( local ) );
@@ -345,7 +315,7 @@ int mbedtls_sha512_update_ret( mbedtls_sha512_context *ctx,
const unsigned char *input,
size_t ilen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t fill;
unsigned int left;
@@ -405,7 +375,7 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx,
int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
unsigned char output[64] )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned used;
uint64_t high, low;
@@ -442,8 +412,8 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
| ( ctx->total[1] << 3 );
low = ( ctx->total[0] << 3 );
- PUT_UINT64_BE( high, ctx->buffer, 112 );
- PUT_UINT64_BE( low, ctx->buffer, 120 );
+ sha512_put_uint64_be( high, ctx->buffer, 112 );
+ sha512_put_uint64_be( low, ctx->buffer, 120 );
if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 )
return( ret );
@@ -451,17 +421,19 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx,
/*
* Output final state
*/
- PUT_UINT64_BE( ctx->state[0], output, 0 );
- PUT_UINT64_BE( ctx->state[1], output, 8 );
- PUT_UINT64_BE( ctx->state[2], output, 16 );
- PUT_UINT64_BE( ctx->state[3], output, 24 );
- PUT_UINT64_BE( ctx->state[4], output, 32 );
- PUT_UINT64_BE( ctx->state[5], output, 40 );
-
+ sha512_put_uint64_be( ctx->state[0], output, 0 );
+ sha512_put_uint64_be( ctx->state[1], output, 8 );
+ sha512_put_uint64_be( ctx->state[2], output, 16 );
+ sha512_put_uint64_be( ctx->state[3], output, 24 );
+ sha512_put_uint64_be( ctx->state[4], output, 32 );
+ sha512_put_uint64_be( ctx->state[5], output, 40 );
+
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
if( ctx->is384 == 0 )
+#endif
{
- PUT_UINT64_BE( ctx->state[6], output, 48 );
- PUT_UINT64_BE( ctx->state[7], output, 56 );
+ sha512_put_uint64_be( ctx->state[6], output, 48 );
+ sha512_put_uint64_be( ctx->state[7], output, 56 );
}
return( 0 );
@@ -485,10 +457,14 @@ int mbedtls_sha512_ret( const unsigned char *input,
unsigned char output[64],
int is384 )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_sha512_context ctx;
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
SHA512_VALIDATE_RET( is384 == 0 || is384 == 1 );
+#else
+ SHA512_VALIDATE_RET( is384 == 0 );
+#endif
SHA512_VALIDATE_RET( ilen == 0 || input != NULL );
SHA512_VALIDATE_RET( (unsigned char *)output != NULL );
@@ -536,8 +512,9 @@ static const size_t sha512_test_buflen[3] =
3, 112, 1000
};
-static const unsigned char sha512_test_sum[6][64] =
+static const unsigned char sha512_test_sum[][64] =
{
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
/*
* SHA-384 test vectors
*/
@@ -559,6 +536,7 @@ static const unsigned char sha512_test_sum[6][64] =
0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B,
0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB,
0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 },
+#endif /* !MBEDTLS_SHA512_NO_SHA384 */
/*
* SHA-512 test vectors
@@ -589,6 +567,8 @@ static const unsigned char sha512_test_sum[6][64] =
0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B }
};
+#define ARRAY_LENGTH( a ) ( sizeof( a ) / sizeof( ( a )[0] ) )
+
/*
* Checkup routine
*/
@@ -610,10 +590,14 @@ int mbedtls_sha512_self_test( int verbose )
mbedtls_sha512_init( &ctx );
- for( i = 0; i < 6; i++ )
+ for( i = 0; i < (int) ARRAY_LENGTH(sha512_test_sum); i++ )
{
j = i % 3;
+#if !defined(MBEDTLS_SHA512_NO_SHA384)
k = i < 3;
+#else
+ k = 0;
+#endif
if( verbose != 0 )
mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 );
@@ -669,6 +653,8 @@ exit:
return( ret );
}
+#undef ARRAY_LENGTH
+
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_SHA512_C */
diff --git a/thirdparty/mbedtls/library/ssl_cache.c b/thirdparty/mbedtls/library/ssl_cache.c
index 1d2558a189..32188cf3f6 100644
--- a/thirdparty/mbedtls/library/ssl_cache.c
+++ b/thirdparty/mbedtls/library/ssl_cache.c
@@ -2,13 +2,7 @@
* SSL session cache implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* These session callbacks use a simple chained list
* to store and retrieve the session information.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_CACHE_C)
@@ -65,6 +34,7 @@
#endif
#include "mbedtls/ssl_cache.h"
+#include "mbedtls/ssl_internal.h"
#include <string.h>
@@ -108,25 +78,31 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
continue;
#endif
- if( session->ciphersuite != entry->session.ciphersuite ||
- session->compression != entry->session.compression ||
- session->id_len != entry->session.id_len )
- continue;
-
- if( memcmp( session->id, entry->session.id,
+ if( session->id_len != entry->session.id_len ||
+ memcmp( session->id, entry->session.id,
entry->session.id_len ) != 0 )
+ {
continue;
+ }
- memcpy( session->master, entry->session.master, 48 );
-
- session->verify_result = entry->session.verify_result;
+ ret = mbedtls_ssl_session_copy( session, &entry->session );
+ if( ret != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* Restore peer certificate (without rest of the original chain)
*/
if( entry->peer_cert.p != NULL )
{
+ /* `session->peer_cert` is NULL after the call to
+ * mbedtls_ssl_session_copy(), because cache entries
+ * have the `peer_cert` field set to NULL. */
+
if( ( session->peer_cert = mbedtls_calloc( 1,
sizeof(mbedtls_x509_crt) ) ) == NULL )
{
@@ -144,7 +120,7 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
goto exit;
}
}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
goto exit;
@@ -264,9 +240,8 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
#endif
}
- memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* If we're reusing an entry, free its certificate first
*/
@@ -275,26 +250,43 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
mbedtls_free( cur->peer_cert.p );
memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+ /* Copy the entire session; this temporarily makes a copy of the
+ * X.509 CRT structure even though we only want to store the raw CRT.
+ * This inefficiency will go away as soon as we implement on-demand
+ * parsing of CRTs, in which case there's no need for the `peer_cert`
+ * field anymore in the first place, and we're done after this call. */
+ ret = mbedtls_ssl_session_copy( &cur->session, session );
+ if( ret != 0 )
+ {
+ ret = 1;
+ goto exit;
+ }
- /*
- * Store peer certificate
- */
- if( session->peer_cert != NULL )
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* If present, free the X.509 structure and only store the raw CRT data. */
+ if( cur->session.peer_cert != NULL )
{
- cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
+ cur->peer_cert.p =
+ mbedtls_calloc( 1, cur->session.peer_cert->raw.len );
if( cur->peer_cert.p == NULL )
{
ret = 1;
goto exit;
}
- memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
- session->peer_cert->raw.len );
+ memcpy( cur->peer_cert.p,
+ cur->session.peer_cert->raw.p,
+ cur->session.peer_cert->raw.len );
cur->peer_cert.len = session->peer_cert->raw.len;
+ mbedtls_x509_crt_free( cur->session.peer_cert );
+ mbedtls_free( cur->session.peer_cert );
cur->session.peer_cert = NULL;
}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
@@ -336,9 +328,10 @@ void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
mbedtls_ssl_session_free( &prv->session );
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_free( prv->peer_cert.p );
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_free( prv );
}
diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c
index 01df17a5f3..3826ad27fa 100644
--- a/thirdparty/mbedtls/library/ssl_ciphersuites.c
+++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c
@@ -4,13 +4,7 @@
* \brief SSL ciphersuites for mbed TLS
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -23,34 +17,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TLS_C)
@@ -65,6 +34,11 @@
#include <string.h>
+#undef HAVE_SHA384
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#define HAVE_SHA384
+#endif
+
/*
* Ordered from most preferred to least preferred in terms of security.
*
@@ -442,7 +416,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -457,7 +431,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_CCM_C)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM",
MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -491,13 +465,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -508,13 +482,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -583,7 +557,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -598,7 +572,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -610,13 +584,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -627,13 +601,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -672,13 +646,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
#if defined(MBEDTLS_AES_C)
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+#if defined(HAVE_SHA384) && defined(MBEDTLS_GCM_C)
{ MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+#endif /* HAVE_SHA384 && MBEDTLS_GCM_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_GCM_C)
@@ -782,13 +756,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -807,13 +781,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
#if defined(MBEDTLS_AES_C)
-#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C)
+#if defined(HAVE_SHA384) && defined(MBEDTLS_GCM_C)
{ MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */
+#endif /* HAVE_SHA384 && MBEDTLS_GCM_C */
#if defined(MBEDTLS_SHA256_C)
#if defined(MBEDTLS_GCM_C)
@@ -918,13 +892,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -991,7 +965,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1006,7 +980,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -1018,13 +992,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1035,13 +1009,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1110,7 +1084,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -1125,7 +1099,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_GCM_C */
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_AES_C */
#if defined(MBEDTLS_CAMELLIA_C)
@@ -1137,13 +1111,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1154,13 +1128,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1208,13 +1182,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1226,13 +1200,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
@@ -1282,13 +1256,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1300,13 +1274,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1344,13 +1318,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1362,13 +1336,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
@@ -1418,13 +1392,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1436,13 +1410,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1481,13 +1455,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA",
@@ -1515,13 +1489,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1559,13 +1533,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384",
MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1577,13 +1551,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384",
MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#if defined(MBEDTLS_SHA1_C)
{ MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
@@ -1611,13 +1585,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_GCM_C)
@@ -1629,13 +1603,13 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
0 },
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384",
MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
-#endif /* MBEDTLS_SHA512_C */
+#endif /* HAVE_SHA384 */
#endif /* MBEDTLS_GCM_C */
#endif /* MBEDTLS_CAMELLIA_C */
@@ -1719,7 +1693,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1745,7 +1719,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1771,7 +1745,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1797,7 +1771,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_CIPHERSUITE_WEAK },
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(HAVE_SHA384)
{ MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384",
MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1,
@@ -1836,7 +1810,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
@@ -1844,7 +1818,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA,
@@ -1873,7 +1847,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
@@ -1881,7 +1855,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-RSA-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK,
@@ -1910,7 +1884,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384,MBEDTLS_KEY_EXCHANGE_PSK,
@@ -1918,7 +1892,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK,
@@ -1947,7 +1921,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1955,7 +1929,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
@@ -1984,7 +1958,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -1992,7 +1966,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
@@ -2021,7 +1995,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
@@ -2042,7 +2016,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -2050,7 +2024,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
@@ -2079,7 +2053,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -2087,7 +2061,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
"TLS-ECDH-ECDSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
@@ -2116,7 +2090,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
@@ -2124,7 +2098,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA,
@@ -2153,7 +2127,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
-#if (defined(MBEDTLS_GCM_C) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_GCM_C) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-GCM-SHA384",
MBEDTLS_CIPHER_ARIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
@@ -2161,7 +2135,7 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
0 },
#endif
-#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(MBEDTLS_SHA512_C))
+#if (defined(MBEDTLS_CIPHER_MODE_CBC) && defined(HAVE_SHA384))
{ MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
"TLS-DHE-PSK-WITH-ARIA-256-CBC-SHA384",
MBEDTLS_CIPHER_ARIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK,
@@ -2378,7 +2352,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
@@ -2393,6 +2367,6 @@ int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info )
return( 0 );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index b977e5b7b1..b87879ce6a 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 client-side functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_CLI_C)
@@ -60,9 +29,16 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+#include "mbedtls/constant_time.h"
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#include <string.h>
@@ -76,6 +52,44 @@
#include "mbedtls/platform_util.h"
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+static int ssl_conf_has_static_psk( mbedtls_ssl_config const *conf )
+{
+ if( conf->psk_identity == NULL ||
+ conf->psk_identity_len == 0 )
+ {
+ return( 0 );
+ }
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
+ return( 1 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_conf_has_static_raw_psk( mbedtls_ssl_config const *conf )
+{
+ if( conf->psk_identity == NULL ||
+ conf->psk_identity_len == 0 )
+ {
+ return( 0 );
+ }
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -124,18 +138,19 @@ static int ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
* } ServerNameList;
*
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SERVERNAME, p, 0 );
+ p += 2;
+
+ MBEDTLS_PUT_UINT16_BE( hostname_len + 5, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( hostname_len + 3, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF );
+ *p++ = MBEDTLS_BYTE_0( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( hostname_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( hostname_len, p, 0 );
+ p += 2;
memcpy( p, ssl->hostname, hostname_len );
@@ -169,14 +184,12 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
/*
* Secure renegotiation
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
*p++ = 0x00;
- *p++ = ( ssl->verify_data_len + 1 ) & 0xFF;
- *p++ = ssl->verify_data_len & 0xFF;
+ *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len + 1 );
+ *p++ = MBEDTLS_BYTE_0( ssl->verify_data_len );
memcpy( p, ssl->own_verify_data, ssl->verify_data_len );
@@ -190,7 +203,7 @@ static int ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
* Only if we handle at least one key exchange that needs signatures.
*/
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
const unsigned char *end,
@@ -271,21 +284,21 @@ static int ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
* SignatureAndHashAlgorithm
* supported_signature_algorithms<2..2^16-2>;
*/
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SIG_ALG, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( sig_alg_len + 2, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( sig_alg_len, p, 0 );
+ p += 2;
*olen = 6 + sig_alg_len;
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -342,20 +355,18 @@ static int ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
grp_id++ )
{
info = mbedtls_ecp_curve_info_from_grp_id( *grp_id );
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
- elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
+ elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_1( info->tls_id );
+ elliptic_curve_list[elliptic_curve_len++] = MBEDTLS_BYTE_0( info->tls_id );
}
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( elliptic_curve_len + 2, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( elliptic_curve_len, p, 0 );
+ p += 2;
*olen = 6 + elliptic_curve_len;
@@ -376,10 +387,8 @@ static int ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
( "client hello, adding supported_point_formats extension" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 2;
@@ -400,7 +409,7 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
const unsigned char *end,
size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
size_t kkpp_len;
@@ -415,8 +424,8 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+ p += 2;
/*
* We may need to send ClientHello multiple times for Hello verification.
@@ -458,8 +467,8 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+ p += 2;
*olen = kkpp_len + 4;
@@ -467,6 +476,52 @@ static int ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_write_cid_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t ext_len;
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+
+ *olen = 0;
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ return( 0 );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding CID extension" ) );
+
+ /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
+ * which is at most 255, so the increment cannot overflow. */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, (unsigned)( ssl->own_cid_len + 5 ) );
+
+ /* Add extension ID + size */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+ p += 2;
+ ext_len = (size_t) ssl->own_cid_len + 1;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ *p++ = (uint8_t) ssl->own_cid_len;
+ memcpy( p, ssl->own_cid, ssl->own_cid_len );
+
+ *olen = ssl->own_cid_len + 5;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -485,10 +540,8 @@ static int ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 5 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 1;
@@ -519,8 +572,8 @@ static int ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -550,8 +603,8 @@ static int ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -581,10 +634,8 @@ static int ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 )
- & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET )
- & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -615,11 +666,11 @@ static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
/* The addition is safe here since the ticket length is 16 bit. */
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 4 + tlen );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+ p += 2;
- *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( tlen ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( tlen, p, 0 );
+ p += 2;
*olen = 4;
@@ -627,7 +678,7 @@ static int ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
return( 0 );
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "sending session ticket of length %d", tlen ) );
+ ( "sending session ticket of length %" MBEDTLS_PRINTF_SIZET, tlen ) );
memcpy( p, ssl->session_negotiate->ticket, tlen );
@@ -659,8 +710,8 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 6 + alpnlen );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, p, 0 );
+ p += 2;
/*
* opaque ProtocolName<1..2^8-1>;
@@ -687,23 +738,139 @@ static int ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
*olen = p - buf;
/* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
/* Extension length = olen - 2 (ext_type) - 2 (ext_len) */
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
return( 0 );
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ const unsigned char *end,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t protection_profiles_index = 0, ext_len = 0;
+ uint16_t mki_len = 0, profile_value = 0;
+
+ *olen = 0;
+
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ {
+ return( 0 );
+ }
+
+ /* RFC 5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+ /* Extension length = 2 bytes for profiles length,
+ * ssl->conf->dtls_srtp_profile_list_len * 2 (each profile is 2 bytes length ),
+ * 1 byte for srtp_mki vector length and the mki_len value
+ */
+ ext_len = 2 + 2 * ( ssl->conf->dtls_srtp_profile_list_len ) + 1 + mki_len;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding use_srtp extension" ) );
+
+ /* Check there is room in the buffer for the extension + 4 bytes
+ * - the extension tag (2 bytes)
+ * - the extension length (2 bytes)
+ */
+ MBEDTLS_SSL_CHK_BUF_PTR( p, end, ext_len + 4 );
+
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_USE_SRTP, p, 0 );
+ p += 2;
+
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ /* protection profile length: 2*(ssl->conf->dtls_srtp_profile_list_len) */
+ /* micro-optimization:
+ * the list size is limited to MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH
+ * which is lower than 127, so the upper byte of the length is always 0
+ * For the documentation, the more generic code is left in comments
+ * *p++ = (unsigned char)( ( ( 2 * ssl->conf->dtls_srtp_profile_list_len )
+ * >> 8 ) & 0xFF );
+ */
+ *p++ = 0;
+ *p++ = MBEDTLS_BYTE_0( 2 * ssl->conf->dtls_srtp_profile_list_len );
+
+ for( protection_profiles_index=0;
+ protection_profiles_index < ssl->conf->dtls_srtp_profile_list_len;
+ protection_profiles_index++ )
+ {
+ profile_value = mbedtls_ssl_check_srtp_profile_value
+ ( ssl->conf->dtls_srtp_profile_list[protection_profiles_index] );
+ if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_write_use_srtp_ext, add profile: %04x",
+ profile_value ) );
+ MBEDTLS_PUT_UINT16_BE( profile_value, p, 0 );
+ p += 2;
+ }
+ else
+ {
+ /*
+ * Note: we shall never arrive here as protection profiles
+ * is checked by mbedtls_ssl_conf_dtls_srtp_protection_profiles function
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 3,
+ ( "client hello, "
+ "illegal DTLS-SRTP protection profile %d",
+ ssl->conf->dtls_srtp_profile_list[protection_profiles_index]
+ ) );
+ return( MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED );
+ }
+ }
+
+ *p++ = mki_len & 0xFF;
+
+ if( mki_len != 0 )
+ {
+ memcpy( p, ssl->dtls_srtp_info.mki_value, mki_len );
+ /*
+ * Increment p to point to the current position.
+ */
+ p += mki_len;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "sending mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+
+ /*
+ * total extension length: extension type (2 bytes)
+ * + extension length (2 bytes)
+ * + protection profile length (2 bytes)
+ * + 2 * number of protection profiles
+ * + srtp_mki vector length(1 byte)
+ * + mki value
+ */
+ *olen = p - buf;
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Generate random bytes for ClientHello
*/
static int ssl_generate_random( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = ssl->handshake->randbytes;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t t;
@@ -722,12 +889,11 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_HAVE_TIME)
t = mbedtls_time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+ p += 4;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
+ (long long) t ) );
#else
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
return( ret );
@@ -782,12 +948,21 @@ static int ssl_validate_ciphersuite(
return( 1 );
#endif
+ /* Don't suggest PSK-based ciphersuite if no PSK is available. */
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+ if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
+ ssl_conf_has_static_psk( ssl->conf ) == 0 )
+ {
+ return( 1 );
+ }
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
return( 0 );
}
static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, olen, ext_len = 0;
unsigned char *buf;
@@ -927,7 +1102,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
for( i = 0; i < n; i++ )
*p++ = ssl->session_negotiate->id[i];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n );
/*
@@ -994,8 +1169,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ssl->conf->max_minor_ver ) != 0 )
continue;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
- ciphersuites[i] ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %#04x (%s)",
+ (unsigned int)ciphersuites[i], ciphersuite_info->name ) );
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1005,12 +1180,12 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
n++;
- *p++ = (unsigned char)( ciphersuites[i] >> 8 );
- *p++ = (unsigned char)( ciphersuites[i] );
+ MBEDTLS_PUT_UINT16_BE( ciphersuites[i], p, 0 );
+ p += 2;
}
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "client hello, got %d ciphersuites (excluding SCSVs)", n ) );
+ ( "client hello, got %" MBEDTLS_PRINTF_SIZET " ciphersuites (excluding SCSVs)", n ) );
/*
* Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -1021,8 +1196,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
n++;
}
@@ -1033,8 +1208,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) );
MBEDTLS_SSL_CHK_BUF_PTR( p, end, 2 );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 );
- *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_SSL_FALLBACK_SCSV_VALUE, p, 0 );
+ p += 2;
n++;
}
#endif
@@ -1109,7 +1284,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
if( ( ret = ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
{
@@ -1151,6 +1326,15 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( ( ret = ssl_write_cid_ext( ssl, p + 2 + ext_len, end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_cid_ext", ret );
+ return( ret );
+ }
+ ext_len += olen;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
if( ( ret = ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
@@ -1201,6 +1385,16 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ if( ( ret = ssl_write_use_srtp_ext( ssl, p + 2 + ext_len,
+ end, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_use_srtp_ext", ret );
+ return( ret );
+ }
+ ext_len += olen;
+#endif
+
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
if( ( ret = ssl_write_session_ticket_ext( ssl, p + 2 + ext_len,
end, &olen ) ) != 0 )
@@ -1214,16 +1408,15 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
/* olen unused if all extensions are disabled */
((void) olen);
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
ext_len ) );
if( ext_len > 0 )
{
/* No need to check for space here, because the extension
* writing functions already took care of that. */
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2 + ext_len;
}
ssl->out_msglen = p - buf;
@@ -1267,9 +1460,9 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len * 2 ||
buf[0] != ssl->verify_data_len * 2 ||
- mbedtls_ssl_safer_memcmp( buf + 1,
+ mbedtls_ct_memcmp( buf + 1,
ssl->own_verify_data, ssl->verify_data_len ) != 0 ||
- mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len,
+ mbedtls_ct_memcmp( buf + 1 + ssl->verify_data_len,
ssl->peer_verify_data, ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -1351,6 +1544,62 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ size_t peer_cid_len;
+
+ if( /* CID extension only makes sense in DTLS */
+ ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ /* The server must only send the CID extension if we have offered it. */
+ ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ if( len == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ peer_cid_len = *buf++;
+ len--;
+
+ if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ if( len != peer_cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
+ ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
+ memcpy( ssl->handshake->peer_cid, buf, peer_cid_len );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Server CID", buf, peer_cid_len );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
@@ -1479,9 +1728,9 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
@@ -1578,6 +1827,123 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ mbedtls_ssl_srtp_profile server_protection = MBEDTLS_TLS_SRTP_UNSET;
+ size_t i, mki_len = 0;
+ uint16_t server_protection_profile_value = 0;
+
+ /* If use_srtp is not configured, just ignore the extension */
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ return( 0 );
+
+ /* RFC 5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ *
+ */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+
+ /*
+ * Length is 5 + optional mki_value : one protection profile length (2 bytes)
+ * + protection profile (2 bytes)
+ * + mki_len(1 byte)
+ * and optional srtp_mki
+ */
+ if( ( len < 5 ) || ( len != ( buf[4] + 5u ) ) )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+ /*
+ * get the server protection profile
+ */
+
+ /*
+ * protection profile length must be 0x0002 as we must have only
+ * one protection profile in server Hello
+ */
+ if( ( buf[0] != 0 ) || ( buf[1] != 2 ) )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+
+ server_protection_profile_value = ( buf[2] << 8 ) | buf[3];
+ server_protection = mbedtls_ssl_check_srtp_profile_value(
+ server_protection_profile_value );
+ if( server_protection != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ server_protection ) ) );
+ }
+
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+ /*
+ * Check we have the server profile in our list
+ */
+ for( i=0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+ {
+ if( server_protection == ssl->conf->dtls_srtp_profile_list[i] )
+ {
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ server_protection ) ) );
+ break;
+ }
+ }
+
+ /* If no match was found : server problem, it shall never answer with incompatible profile */
+ if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
+ /* If server does not use mki in its reply, make sure the client won't keep
+ * one as negotiated */
+ if( len == 5 )
+ {
+ ssl->dtls_srtp_info.mki_len = 0;
+ }
+
+ /*
+ * RFC5764:
+ * If the client detects a nonzero-length MKI in the server's response
+ * that is different than the one the client offered, then the client
+ * MUST abort the handshake and SHOULD send an invalid_parameter alert.
+ */
+ if( len > 5 && ( buf[4] != mki_len ||
+ ( memcmp( ssl->dtls_srtp_info.mki_value, &buf[5], mki_len ) ) ) )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+#if defined (MBEDTLS_DEBUG_C)
+ if( len > 5 )
+ {
+ MBEDTLS_SSL_DEBUG_BUF( 3, "received mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+#endif
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Parse HelloVerifyRequest. Only called after verifying the HS type.
*/
@@ -1683,8 +2049,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) );
- buf = ssl->in_msg;
-
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{
/* No alert on a read error. */
@@ -1692,6 +2056,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( ret );
}
+ buf = ssl->in_msg;
+
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
#if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -1788,10 +2154,10 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu",
- ( (uint32_t) buf[2] << 24 ) |
- ( (uint32_t) buf[3] << 16 ) |
- ( (uint32_t) buf[4] << 8 ) |
- ( (uint32_t) buf[5] ) ) );
+ ( (unsigned long) buf[2] << 24 ) |
+ ( (unsigned long) buf[3] << 16 ) |
+ ( (unsigned long) buf[4] << 8 ) |
+ ( (unsigned long) buf[5] ) ) );
memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 );
@@ -1870,22 +2236,19 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
/*
* Initialize update checksum functions
*/
- ssl->transform_negotiate->ciphersuite_info =
- mbedtls_ssl_ciphersuite_from_id( i );
-
- if( ssl->transform_negotiate->ciphersuite_info == NULL )
+ ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
+ if( ssl->handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
- ( "ciphersuite info for %04x not found", i ) );
+ ( "ciphersuite info for %04x not found", (unsigned int)i ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- mbedtls_ssl_optimize_checksum( ssl,
- ssl->transform_negotiate->ciphersuite_info );
+ mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
/*
@@ -1928,7 +2291,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", (unsigned) i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d",
buf[37 + n] ) );
@@ -1971,7 +2334,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3,
( "server hello, chosen ciphersuite: %s", suite_info->name ) );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA &&
ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
@@ -1997,7 +2360,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
ext = buf + 40 + n;
MBEDTLS_SSL_DEBUG_MSG( 2,
- ( "server hello, total extension length: %d", ext_len ) );
+ ( "server hello, total extension length: %" MBEDTLS_PRINTF_SIZET, ext_len ) );
while( ext_len )
{
@@ -2056,6 +2419,20 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ case MBEDTLS_TLS_EXT_CID:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
+
+ if( ( ret = ssl_parse_cid_ext( ssl,
+ ext + 4,
+ ext_size ) ) != 0 )
+ {
+ return( ret );
+ }
+
+ break;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) );
@@ -2135,9 +2512,19 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break;
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ case MBEDTLS_TLS_EXT_USE_SRTP:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+ if( ( ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size ) ) != 0 )
+ return( ret );
+
+ break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
default:
MBEDTLS_SSL_DEBUG_MSG( 3,
- ( "unknown extension found: %d (ignoring)", ext_id ) );
+ ( "unknown extension found: %u (ignoring)", ext_id ) );
}
ext_len -= 4 + ext_size;
@@ -2230,8 +2617,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl,
dhm_actual_bitlen = mbedtls_mpi_bitlen( &ssl->handshake->dhm_ctx.P );
if( dhm_actual_bitlen < ssl->conf->dhm_min_bitlen )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %u < %u",
- (unsigned) dhm_actual_bitlen,
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %" MBEDTLS_PRINTF_SIZET " < %u",
+ dhm_actual_bitlen,
ssl->conf->dhm_min_bitlen ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
@@ -2288,6 +2675,68 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+static int ssl_parse_server_ecdh_params_psa( mbedtls_ssl_context *ssl,
+ unsigned char **p,
+ unsigned char *end )
+{
+ uint16_t tls_id;
+ size_t ecdh_bits = 0;
+ uint8_t ecpoint_len;
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ /*
+ * Parse ECC group
+ */
+
+ if( end - *p < 4 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ /* First byte is curve_type; only named_curve is handled */
+ if( *(*p)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ /* Next two bytes are the namedcurve value */
+ tls_id = *(*p)++;
+ tls_id <<= 8;
+ tls_id |= *(*p)++;
+
+ /* Convert EC group to PSA key type. */
+ if( ( handshake->ecdh_psa_type =
+ mbedtls_psa_parse_tls_ecc_group( tls_id, &ecdh_bits ) ) == 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ }
+ if( ecdh_bits > 0xffff )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ handshake->ecdh_bits = (uint16_t) ecdh_bits;
+
+ /*
+ * Put peer's ECDH public key in the format understood by PSA.
+ */
+
+ ecpoint_len = *(*p)++;
+ if( (size_t)( end - *p ) < ecpoint_len )
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+
+ if( mbedtls_psa_tls_ecpoint_to_psa_ec(
+ *p, ecpoint_len,
+ handshake->ecdh_psa_peerkey,
+ sizeof( handshake->ecdh_psa_peerkey ),
+ &handshake->ecdh_psa_peerkey_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ *p += ecpoint_len;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
+
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
@@ -2309,7 +2758,7 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
(const unsigned char **) p, end ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -2329,13 +2778,13 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
unsigned char **p,
unsigned char *end )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
- size_t len;
+ uint16_t len;
((void) ssl);
/*
@@ -2352,7 +2801,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
len = (*p)[0] << 8 | (*p)[1];
*p += 2;
- if( end - (*p) < (int) len )
+ if( end - (*p) < len )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "bad server key exchange message (psk_identity_hint length)" ) );
@@ -2369,7 +2818,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
return( ret );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
@@ -2380,9 +2829,10 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
size_t offset, size_t *olen,
size_t pms_offset )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
unsigned char *p = ssl->handshake->premaster + pms_offset;
+ mbedtls_pk_context * peer_pk;
if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
@@ -2409,23 +2859,28 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
ssl->handshake->pmslen = 48;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Now write it out, encrypted
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_RSA ) )
+ if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
- if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_encrypt( peer_pk,
p, ssl->handshake->pmslen,
ssl->out_msg + offset + len_bytes, olen,
MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
@@ -2439,12 +2894,15 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( len_bytes == 2 )
{
- ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 );
- ssl->out_msg[offset+1] = (unsigned char)( *olen );
+ MBEDTLS_PUT_UINT16_BE( *olen, ssl->out_msg, offset );
*olen += 2;
}
#endif
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
@@ -2522,23 +2980,29 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ecp_keypair *peer_key;
+ mbedtls_pk_context * peer_pk;
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECKEY ) )
+ if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
- peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
+ peer_key = mbedtls_pk_ec( *peer_pk );
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
MBEDTLS_ECDH_THEIRS ) ) != 0 )
@@ -2553,6 +3017,13 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it,
+ * so that more RAM is available for upcoming expensive
+ * operations like ECDHE. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
return( ret );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
@@ -2560,9 +3031,9 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
unsigned char *p = NULL, *end = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@@ -2602,7 +3073,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_ske_start_processing )
{
@@ -2651,7 +3122,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_ske_start_processing;
@@ -2661,7 +3132,7 @@ start_processing:
end = ssl->in_msg + ssl->in_hslen;
MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -2677,7 +3148,7 @@ start_processing:
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
} /* FALLTROUGH */
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
@@ -2705,6 +3176,26 @@ start_processing:
else
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+ ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+ {
+ if( ssl_parse_server_ecdh_params_psa( ssl, &p, end ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
+ mbedtls_ssl_send_alert_message(
+ ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
+ }
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
@@ -2748,17 +3239,23 @@ start_processing:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{
size_t sig_len, hashlen;
- unsigned char hash[64];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
+ unsigned char hash[MBEDTLS_MD_MAX_SIZE];
+#endif
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
size_t params_len = p - params;
void *rs_ctx = NULL;
+ mbedtls_pk_context * peer_pk;
+
/*
* Handle the digitally-signed structure
*/
@@ -2872,21 +3369,22 @@ start_processing:
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
- mbedtls_ssl_send_alert_message(
- ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ /* Should never happen */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Verify signature
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- pk_alg ) )
+ if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message(
@@ -2896,16 +3394,15 @@ start_processing:
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
- if( ( ret = mbedtls_pk_verify_restartable(
- &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_verify_restartable( peer_pk,
md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
{
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
#endif
mbedtls_ssl_send_alert_message(
@@ -2913,14 +3410,21 @@ start_processing:
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR );
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret );
}
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* We don't need the peer's public key anymore. Free it,
+ * so that more RAM is available for upcoming expensive
+ * operations like ECDHE. */
+ mbedtls_pk_free( peer_pk );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
exit:
ssl->state++;
@@ -2930,11 +3434,11 @@ exit:
return( 0 );
}
-#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
+#if ! defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -2948,15 +3452,15 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+#else /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *buf;
size_t n = 0;
size_t cert_type_len = 0, dn_len = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@@ -3118,11 +3622,11 @@ exit:
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
@@ -3161,10 +3665,12 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
- size_t i, n;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ size_t header_len;
+ size_t content_len;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
@@ -3174,15 +3680,14 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
/*
* DHM key exchange -- send G^X mod P
*/
- n = ssl->handshake->dhm_ctx.len;
+ content_len = ssl->handshake->dhm_ctx.len;
- ssl->out_msg[4] = (unsigned char)( n >> 8 );
- ssl->out_msg[5] = (unsigned char)( n );
- i = 6;
+ MBEDTLS_PUT_UINT16_BE( content_len, ssl->out_msg, 4 );
+ header_len = 6;
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
+ &ssl->out_msg[header_len], content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3207,6 +3712,93 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ ( defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) )
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
+ ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
+ {
+ psa_status_t status;
+ psa_key_attributes_t key_attributes;
+
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ unsigned char own_pubkey[MBEDTLS_PSA_MAX_EC_PUBKEY_LENGTH];
+ size_t own_pubkey_len;
+ unsigned char *own_pubkey_ecpoint;
+ size_t own_pubkey_ecpoint_len;
+
+ header_len = 4;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Perform PSA-based ECDH computation." ) );
+
+ /*
+ * Generate EC private key for ECDHE exchange.
+ */
+
+ /* The master secret is obtained from the shared ECDH secret by
+ * applying the TLS 1.2 PRF with a specific salt and label. While
+ * the PSA Crypto API encourages combining key agreement schemes
+ * such as ECDH with fixed KDFs such as TLS 1.2 PRF, it does not
+ * yet support the provisioning of salt + label to the KDF.
+ * For the time being, we therefore need to split the computation
+ * of the ECDH secret and the application of the TLS 1.2 PRF. */
+ key_attributes = psa_key_attributes_init();
+ psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &key_attributes, PSA_ALG_ECDH );
+ psa_set_key_type( &key_attributes, handshake->ecdh_psa_type );
+ psa_set_key_bits( &key_attributes, handshake->ecdh_bits );
+
+ /* Generate ECDH private key. */
+ status = psa_generate_key( &key_attributes,
+ &handshake->ecdh_psa_privkey );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ /* Export the public part of the ECDH private key from PSA
+ * and convert it to ECPoint format used in ClientKeyExchange. */
+ status = psa_export_public_key( handshake->ecdh_psa_privkey,
+ own_pubkey, sizeof( own_pubkey ),
+ &own_pubkey_len );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ if( mbedtls_psa_tls_psa_ec_to_ecpoint( own_pubkey,
+ own_pubkey_len,
+ &own_pubkey_ecpoint,
+ &own_pubkey_ecpoint_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ /* Copy ECPoint structure to outgoing message buffer. */
+ ssl->out_msg[header_len] = (unsigned char) own_pubkey_ecpoint_len;
+ memcpy( ssl->out_msg + header_len + 1,
+ own_pubkey_ecpoint, own_pubkey_ecpoint_len );
+ content_len = own_pubkey_ecpoint_len + 1;
+
+ /* The ECDH secret is the premaster secret used for key derivation. */
+
+ /* Compute ECDH shared secret. */
+ status = psa_raw_key_agreement( PSA_ALG_ECDH,
+ handshake->ecdh_psa_privkey,
+ handshake->ecdh_psa_peerkey,
+ handshake->ecdh_psa_peerkey_len,
+ ssl->handshake->premaster,
+ sizeof( ssl->handshake->premaster ),
+ &ssl->handshake->pmslen );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ status = psa_destroy_key( handshake->ecdh_psa_privkey );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ handshake->ecdh_psa_privkey = MBEDTLS_SVC_KEY_ID_INIT;
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ ( MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
+ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ) */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@@ -3219,9 +3811,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
/*
* ECDH key exchange -- send client public value
*/
- i = 4;
+ header_len = 4;
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
{
if( ssl->handshake->ecrs_state == ssl_ecrs_cke_ecdh_calc_secret )
@@ -3232,13 +3824,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
#endif
ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
- &n,
- &ssl->out_msg[i], 1000,
+ &content_len,
+ &ssl->out_msg[header_len], 1000,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -3248,16 +3840,16 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
{
- ssl->handshake->ecrs_n = n;
+ ssl->handshake->ecrs_n = content_len;
ssl->handshake->ecrs_state = ssl_ecrs_cke_ecdh_calc_secret;
}
ecdh_calc_secret:
if( ssl->handshake->ecrs_enabled )
- n = ssl->handshake->ecrs_n;
+ content_len = ssl->handshake->ecrs_n;
#endif
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen,
@@ -3266,7 +3858,7 @@ ecdh_calc_secret:
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
@@ -3281,47 +3873,56 @@ ecdh_calc_secret:
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) )
{
/*
* opaque psk_identity<0..2^16-1>;
*/
- if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL )
+ if( ssl_conf_has_static_psk( ssl->conf ) == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) );
- return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
+ /* We don't offer PSK suites if we don't have a PSK,
+ * and we check that the server's choice is among the
+ * ciphersuites we offered, so this should never happen. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- i = 4;
- n = ssl->conf->psk_identity_len;
+ header_len = 4;
+ content_len = ssl->conf->psk_identity_len;
- if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ if( header_len + 2 + content_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "psk identity too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
- memcpy( ssl->out_msg + i,
+ memcpy( ssl->out_msg + header_len,
ssl->conf->psk_identity,
ssl->conf->psk_identity_len );
- i += ssl->conf->psk_identity_len;
+ header_len += ssl->conf->psk_identity_len;
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK )
{
- n = 0;
+ content_len = 0;
}
else
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
{
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 )
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
+ &content_len, 2 ) ) != 0 )
return( ret );
}
else
@@ -3329,24 +3930,31 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* ClientDiffieHellmanPublic public (DHM send G^X mod P)
*/
- n = ssl->handshake->dhm_ctx.len;
+ content_len = ssl->handshake->dhm_ctx.len;
- if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ if( header_len + 2 + content_len >
+ MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
( "psk identity or DHM size too long or SSL buffer too short" ) );
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
}
- ssl->out_msg[i++] = (unsigned char)( n >> 8 );
- ssl->out_msg[i++] = (unsigned char)( n );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_1( content_len );
+ ssl->out_msg[header_len++] = MBEDTLS_BYTE_0( content_len );
ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx,
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
- &ssl->out_msg[i], n,
+ &ssl->out_msg[header_len], content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3359,11 +3967,19 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only suites. */
+ if( ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
/*
* ClientECDiffieHellmanPublic public;
*/
- ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n,
- &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i,
+ ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx,
+ &content_len,
+ &ssl->out_msg[header_len],
+ MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3381,6 +3997,18 @@ ecdh_calc_secret:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
+ ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ ssl_conf_has_static_raw_psk( ssl->conf ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "skip PMS generation for opaque PSK" ) );
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 )
{
@@ -3390,12 +4018,13 @@ ecdh_calc_secret:
}
}
else
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA )
{
- i = 4;
- if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 )
+ header_len = 4;
+ if( ( ret = ssl_write_encrypted_pms( ssl, header_len,
+ &content_len, 0 ) ) != 0 )
return( ret );
}
else
@@ -3403,10 +4032,12 @@ ecdh_calc_secret:
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
- i = 4;
+ header_len = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
- ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n,
+ ssl->out_msg + header_len,
+ MBEDTLS_SSL_OUT_CONTENT_LEN - header_len,
+ &content_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
@@ -3431,7 +4062,7 @@ ecdh_calc_secret:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- ssl->out_msglen = i + n;
+ ssl->out_msglen = header_len + content_len;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE;
@@ -3448,17 +4079,12 @@ ecdh_calc_secret:
return( 0 );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
- int ret;
+ ssl->handshake->ciphersuite_info;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@@ -3468,11 +4094,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@@ -3482,22 +4104,22 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
size_t n = 0, offset = 0;
unsigned char hash[48];
unsigned char *hash_start = hash;
mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE;
- unsigned int hashlen;
+ size_t hashlen;
void *rs_ctx = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled &&
ssl->handshake->ecrs_state == ssl_ecrs_crt_vrfy_sign )
{
@@ -3511,11 +4133,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@@ -3538,14 +4156,14 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Make a signature of the handshake digests
*/
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
ssl->handshake->ecrs_state = ssl_ecrs_crt_vrfy_sign;
sign:
#endif
- ssl->handshake->calc_verify( ssl, hash );
+ ssl->handshake->calc_verify( ssl, hash, &hashlen );
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_1)
@@ -3563,7 +4181,6 @@ sign:
* sha_hash
* SHA(handshake_messages);
*/
- hashlen = 36;
md_alg = MBEDTLS_MD_NONE;
/*
@@ -3598,8 +4215,7 @@ sign:
* SHA224 in order to satisfy 'weird' needs from the server
* side.
*/
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
+ if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
{
md_alg = MBEDTLS_MD_SHA384;
ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;
@@ -3622,7 +4238,7 @@ sign:
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ssl->handshake->ecrs_enabled )
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
@@ -3633,15 +4249,14 @@ sign:
ssl->conf->f_rng, ssl->conf->p_rng, rs_ctx ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS;
#endif
return( ret );
}
- ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
- ssl->out_msg[5 + offset] = (unsigned char)( n );
+ MBEDTLS_PUT_UINT16_BE( n, ssl->out_msg, offset + 4 );
ssl->out_msglen = 6 + n + offset;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -3659,17 +4274,12 @@ sign:
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t lifetime;
size_t ticket_len;
unsigned char *ticket;
@@ -3727,7 +4337,7 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, ticket_len ) );
/* We're not waiting for a NewSessionTicket message any more */
ssl->handshake->new_session_ticket = 0;
@@ -3740,6 +4350,15 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
if( ticket_len == 0 )
return( 0 );
+ if( ssl->session != NULL && ssl->session->ticket != NULL )
+ {
+ mbedtls_platform_zeroize( ssl->session->ticket,
+ ssl->session->ticket_len );
+ mbedtls_free( ssl->session->ticket );
+ ssl->session->ticket = NULL;
+ ssl->session->ticket_len = 0;
+ }
+
mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
ssl->session_negotiate->ticket_len );
mbedtls_free( ssl->session_negotiate->ticket );
diff --git a/thirdparty/mbedtls/library/ssl_cookie.c b/thirdparty/mbedtls/library/ssl_cookie.c
index 9e2136865d..abf29ae717 100644
--- a/thirdparty/mbedtls/library/ssl_cookie.c
+++ b/thirdparty/mbedtls/library/ssl_cookie.c
@@ -2,13 +2,7 @@
* DTLS cookie callbacks implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,38 +15,13 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* These session callbacks use a simple chained list
* to store and retrieve the session information.
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_COOKIE_C)
@@ -65,7 +34,9 @@
#include "mbedtls/ssl_cookie.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -129,7 +100,7 @@ int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char key[COOKIE_MD_OUTLEN];
if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 )
@@ -181,7 +152,7 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
unsigned char **p, unsigned char *end,
const unsigned char *cli_id, size_t cli_id_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
unsigned long t;
@@ -196,15 +167,12 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
t = ctx->serial++;
#endif
- (*p)[0] = (unsigned char)( t >> 24 );
- (*p)[1] = (unsigned char)( t >> 16 );
- (*p)[2] = (unsigned char)( t >> 8 );
- (*p)[3] = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE(t, *p, 0);
*p += 4;
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret ) );
#endif
ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4,
@@ -212,8 +180,8 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
+ MBEDTLS_ERR_THREADING_MUTEX_ERROR ) );
#endif
return( ret );
@@ -240,7 +208,7 @@ int mbedtls_ssl_cookie_check( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret ) );
#endif
if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie,
@@ -250,14 +218,16 @@ int mbedtls_ssl_cookie_check( void *p_ctx,
#if defined(MBEDTLS_THREADING_C)
if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
- ret = ( MBEDTLS_ERR_SSL_INTERNAL_ERROR +
- MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ {
+ ret = MBEDTLS_ERROR_ADD( MBEDTLS_ERR_SSL_INTERNAL_ERROR,
+ MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+ }
#endif
if( ret != 0 )
goto exit;
- if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
+ if( mbedtls_ct_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 )
{
ret = -1;
goto exit;
diff --git a/thirdparty/mbedtls/library/ssl_msg.c b/thirdparty/mbedtls/library/ssl_msg.c
new file mode 100644
index 0000000000..0b696dd561
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_msg.c
@@ -0,0 +1,5922 @@
+/*
+ * Generic SSL/TLS messaging layer functions
+ * (record layer + retransmission state machine)
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * The SSL 3.0 specification was drafted by Netscape in 1996,
+ * and became an IETF standard in 1999.
+ *
+ * http://wp.netscape.com/eng/ssl3/
+ * http://www.ietf.org/rfc/rfc2246.txt
+ * http://www.ietf.org/rfc/rfc4346.txt
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_TLS_C)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+#include "mbedtls/ssl.h"
+#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
+#include "mbedtls/platform_util.h"
+#include "mbedtls/version.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "mbedtls/oid.h"
+#endif
+
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
+
+/*
+ * Start a timer.
+ * Passing millisecs = 0 cancels a running timer.
+ */
+void mbedtls_ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
+{
+ if( ssl->f_set_timer == NULL )
+ return;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
+ ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
+}
+
+/*
+ * Return -1 is timer is expired, 0 if it isn't.
+ */
+int mbedtls_ssl_check_timer( mbedtls_ssl_context *ssl )
+{
+ if( ssl->f_get_timer == NULL )
+ return( 0 );
+
+ if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t len,
+ mbedtls_record *rec );
+
+int mbedtls_ssl_check_record( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t buflen )
+{
+ int ret = 0;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "=> mbedtls_ssl_check_record" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "record buffer", buf, buflen );
+
+ /* We don't support record checking in TLS because
+ * (a) there doesn't seem to be a usecase for it, and
+ * (b) In SSLv3 and TLS 1.0, CBC record decryption has state
+ * and we'd need to backup the transform here.
+ */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
+ {
+ ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ goto exit;
+ }
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ else
+ {
+ mbedtls_record rec;
+
+ ret = ssl_parse_record_header( ssl, buf, buflen, &rec );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 3, "ssl_parse_record_header", ret );
+ goto exit;
+ }
+
+ if( ssl->transform_in != NULL )
+ {
+ ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in, &rec );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 3, "mbedtls_ssl_decrypt_buf", ret );
+ goto exit;
+ }
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+exit:
+ /* On success, we have decrypted the buffer in-place, so make
+ * sure we don't leak any plaintext data. */
+ mbedtls_platform_zeroize( buf, buflen );
+
+ /* For the purpose of this API, treat messages with unexpected CID
+ * as well as such from future epochs as unexpected. */
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID ||
+ ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "<= mbedtls_ssl_check_record" ) );
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+
+#define SSL_DONT_FORCE_FLUSH 0
+#define SSL_FORCE_FLUSH 1
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+/* Forward declarations for functions related to message buffering. */
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+ uint8_t slot );
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
+static int ssl_buffer_message( mbedtls_ssl_context *ssl );
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
+ mbedtls_record const *rec );
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
+
+static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
+{
+ size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ if( mtu != 0 && mtu < out_buf_len )
+ return( mtu );
+
+ return( out_buf_len );
+}
+
+static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ size_t const bytes_written = ssl->out_left;
+ size_t const mtu = ssl_get_maximum_datagram_size( ssl );
+
+ /* Double-check that the write-index hasn't gone
+ * past what we can transmit in a single datagram. */
+ if( bytes_written > mtu )
+ {
+ /* Should never happen... */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ return( (int) ( mtu - bytes_written ) );
+}
+
+static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t remaining, expansion;
+ size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
+
+ if( max_len > mfl )
+ max_len = mfl;
+
+ /* By the standard (RFC 6066 Sect. 4), the MFL extension
+ * only limits the maximum record payload size, so in theory
+ * we would be allowed to pack multiple records of payload size
+ * MFL into a single datagram. However, this would mean that there's
+ * no way to explicitly communicate MTU restrictions to the peer.
+ *
+ * The following reduction of max_len makes sure that we never
+ * write datagrams larger than MFL + Record Expansion Overhead.
+ */
+ if( max_len <= ssl->out_left )
+ return( 0 );
+
+ max_len -= ssl->out_left;
+#endif
+
+ ret = ssl_get_remaining_space_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ remaining = (size_t) ret;
+
+ ret = mbedtls_ssl_get_record_expansion( ssl );
+ if( ret < 0 )
+ return( ret );
+ expansion = (size_t) ret;
+
+ if( remaining <= expansion )
+ return( 0 );
+
+ remaining -= expansion;
+ if( remaining >= max_len )
+ remaining = max_len;
+
+ return( (int) remaining );
+}
+
+/*
+ * Double the retransmit timeout value, within the allowed range,
+ * returning -1 if the maximum value has already been reached.
+ */
+static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+ uint32_t new_timeout;
+
+ if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
+ return( -1 );
+
+ /* Implement the final paragraph of RFC 6347 section 4.1.1.1
+ * in the following way: after the initial transmission and a first
+ * retransmission, back off to a temporary estimated MTU of 508 bytes.
+ * This value is guaranteed to be deliverable (if not guaranteed to be
+ * delivered) of any compliant IPv4 (and IPv6) network, and should work
+ * on most non-IP stacks too. */
+ if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
+ {
+ ssl->handshake->mtu = 508;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
+ }
+
+ new_timeout = 2 * ssl->handshake->retransmit_timeout;
+
+ /* Avoid arithmetic overflow and range overflow */
+ if( new_timeout < ssl->handshake->retransmit_timeout ||
+ new_timeout > ssl->conf->hs_timeout_max )
+ {
+ new_timeout = ssl->conf->hs_timeout_max;
+ }
+
+ ssl->handshake->retransmit_timeout = new_timeout;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
+ (unsigned long) ssl->handshake->retransmit_timeout ) );
+
+ return( 0 );
+}
+
+static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
+{
+ ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %lu millisecs",
+ (unsigned long) ssl->handshake->retransmit_timeout ) );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
+ const unsigned char *key_enc, const unsigned char *key_dec,
+ size_t keylen,
+ const unsigned char *iv_enc, const unsigned char *iv_dec,
+ size_t ivlen,
+ const unsigned char *mac_enc, const unsigned char *mac_dec,
+ size_t maclen ) = NULL;
+int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
+int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
+int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+/*
+ * Encryption/decryption functions
+ */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+static size_t ssl_compute_padding_length( size_t len,
+ size_t granularity )
+{
+ return( ( granularity - ( len + 1 ) % granularity ) % granularity );
+}
+
+/* This functions transforms a (D)TLS plaintext fragment and a record content
+ * type into an instance of the (D)TLSInnerPlaintext structure. This is used
+ * in DTLS 1.2 + CID and within TLS 1.3 to allow flexible padding and to protect
+ * a record's content type.
+ *
+ * struct {
+ * opaque content[DTLSPlaintext.length];
+ * ContentType real_type;
+ * uint8 zeros[length_of_padding];
+ * } (D)TLSInnerPlaintext;
+ *
+ * Input:
+ * - `content`: The beginning of the buffer holding the
+ * plaintext to be wrapped.
+ * - `*content_size`: The length of the plaintext in Bytes.
+ * - `max_len`: The number of Bytes available starting from
+ * `content`. This must be `>= *content_size`.
+ * - `rec_type`: The desired record content type.
+ *
+ * Output:
+ * - `content`: The beginning of the resulting (D)TLSInnerPlaintext structure.
+ * - `*content_size`: The length of the resulting (D)TLSInnerPlaintext structure.
+ *
+ * Returns:
+ * - `0` on success.
+ * - A negative error code if `max_len` didn't offer enough space
+ * for the expansion.
+ */
+static int ssl_build_inner_plaintext( unsigned char *content,
+ size_t *content_size,
+ size_t remaining,
+ uint8_t rec_type,
+ size_t pad )
+{
+ size_t len = *content_size;
+
+ /* Write real content type */
+ if( remaining == 0 )
+ return( -1 );
+ content[ len ] = rec_type;
+ len++;
+ remaining--;
+
+ if( remaining < pad )
+ return( -1 );
+ memset( content + len, 0, pad );
+ len += pad;
+ remaining -= pad;
+
+ *content_size = len;
+ return( 0 );
+}
+
+/* This function parses a (D)TLSInnerPlaintext structure.
+ * See ssl_build_inner_plaintext() for details. */
+static int ssl_parse_inner_plaintext( unsigned char const *content,
+ size_t *content_size,
+ uint8_t *rec_type )
+{
+ size_t remaining = *content_size;
+
+ /* Determine length of padding by skipping zeroes from the back. */
+ do
+ {
+ if( remaining == 0 )
+ return( -1 );
+ remaining--;
+ } while( content[ remaining ] == 0 );
+
+ *content_size = remaining;
+ *rec_type = content[ remaining ];
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID ||
+ MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+/* `add_data` must have size 13 Bytes if the CID extension is disabled,
+ * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */
+static void ssl_extract_add_data_from_record( unsigned char* add_data,
+ size_t *add_data_len,
+ mbedtls_record *rec,
+ unsigned minor_ver )
+{
+ /* Quoting RFC 5246 (TLS 1.2):
+ *
+ * additional_data = seq_num + TLSCompressed.type +
+ * TLSCompressed.version + TLSCompressed.length;
+ *
+ * For the CID extension, this is extended as follows
+ * (quoting draft-ietf-tls-dtls-connection-id-05,
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05):
+ *
+ * additional_data = seq_num + DTLSPlaintext.type +
+ * DTLSPlaintext.version +
+ * cid +
+ * cid_length +
+ * length_of_DTLSInnerPlaintext;
+ *
+ * For TLS 1.3, the record sequence number is dropped from the AAD
+ * and encoded within the nonce of the AEAD operation instead.
+ */
+
+ unsigned char *cur = add_data;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( minor_ver != MBEDTLS_SSL_MINOR_VERSION_4 )
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+ {
+ ((void) minor_ver);
+ memcpy( cur, rec->ctr, sizeof( rec->ctr ) );
+ cur += sizeof( rec->ctr );
+ }
+
+ *cur = rec->type;
+ cur++;
+
+ memcpy( cur, rec->ver, sizeof( rec->ver ) );
+ cur += sizeof( rec->ver );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( rec->cid_len != 0 )
+ {
+ memcpy( cur, rec->cid, rec->cid_len );
+ cur += rec->cid_len;
+
+ *cur = rec->cid_len;
+ cur++;
+
+ MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
+ cur += 2;
+ }
+ else
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ {
+ MBEDTLS_PUT_UINT16_BE( rec->data_len, cur, 0 );
+ cur += 2;
+ }
+
+ *add_data_len = cur - add_data;
+}
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+
+#define SSL3_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
+
+/*
+ * SSLv3.0 MAC functions
+ */
+static int ssl_mac( mbedtls_md_context_t *md_ctx,
+ const unsigned char *secret,
+ const unsigned char *buf, size_t len,
+ const unsigned char *ctr, int type,
+ unsigned char out[SSL3_MAC_MAX_BYTES] )
+{
+ unsigned char header[11];
+ unsigned char padding[48];
+ int padlen;
+ int md_size = mbedtls_md_get_size( md_ctx->md_info );
+ int md_type = mbedtls_md_get_type( md_ctx->md_info );
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Only MD5 and SHA-1 supported */
+ if( md_type == MBEDTLS_MD_MD5 )
+ padlen = 48;
+ else
+ padlen = 40;
+
+ memcpy( header, ctr, 8 );
+ header[8] = (unsigned char) type;
+ MBEDTLS_PUT_UINT16_BE( len, header, 9);
+
+ memset( padding, 0x36, padlen );
+ ret = mbedtls_md_starts( md_ctx );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, secret, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, padding, padlen );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, header, 11 );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, buf, len );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_finish( md_ctx, out );
+ if( ret != 0 )
+ return( ret );
+
+ memset( padding, 0x5C, padlen );
+ ret = mbedtls_md_starts( md_ctx );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, secret, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, padding, padlen );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_update( md_ctx, out, md_size );
+ if( ret != 0 )
+ return( ret );
+ ret = mbedtls_md_finish( md_ctx, out );
+ if( ret != 0 )
+ return( ret );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+static int ssl_transform_aead_dynamic_iv_is_explicit(
+ mbedtls_ssl_transform const *transform )
+{
+ return( transform->ivlen != transform->fixed_ivlen );
+}
+
+/* Compute IV := ( fixed_iv || 0 ) XOR ( 0 || dynamic_IV )
+ *
+ * Concretely, this occurs in two variants:
+ *
+ * a) Fixed and dynamic IV lengths add up to total IV length, giving
+ * IV = fixed_iv || dynamic_iv
+ *
+ * This variant is used in TLS 1.2 when used with GCM or CCM.
+ *
+ * b) Fixed IV lengths matches total IV length, giving
+ * IV = fixed_iv XOR ( 0 || dynamic_iv )
+ *
+ * This variant occurs in TLS 1.3 and for TLS 1.2 when using ChaChaPoly.
+ *
+ * See also the documentation of mbedtls_ssl_transform.
+ *
+ * This function has the precondition that
+ *
+ * dst_iv_len >= max( fixed_iv_len, dynamic_iv_len )
+ *
+ * which has to be ensured by the caller. If this precondition
+ * violated, the behavior of this function is undefined.
+ */
+static void ssl_build_record_nonce( unsigned char *dst_iv,
+ size_t dst_iv_len,
+ unsigned char const *fixed_iv,
+ size_t fixed_iv_len,
+ unsigned char const *dynamic_iv,
+ size_t dynamic_iv_len )
+{
+ size_t i;
+
+ /* Start with Fixed IV || 0 */
+ memset( dst_iv, 0, dst_iv_len );
+ memcpy( dst_iv, fixed_iv, fixed_iv_len );
+
+ dst_iv += dst_iv_len - dynamic_iv_len;
+ for( i = 0; i < dynamic_iv_len; i++ )
+ dst_iv[i] ^= dynamic_iv[i];
+}
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+
+int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec,
+ int (*f_rng)(void *, unsigned char *, size_t),
+ void *p_rng )
+{
+ mbedtls_cipher_mode_t mode;
+ int auth_done = 0;
+ unsigned char * data;
+ unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+ size_t add_data_len;
+ size_t post_avail;
+
+ /* The SSL context is only used for debugging purposes! */
+#if !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for debug */
+ ((void) ssl);
+#endif
+
+ /* The PRNG is used for dynamic IV generation that's used
+ * for CBC transformations in TLS 1.1 and TLS 1.2. */
+#if !( defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC) && \
+ ( defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) ) )
+ ((void) f_rng);
+ ((void) p_rng);
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
+
+ if( transform == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ if( rec == NULL
+ || rec->buf == NULL
+ || rec->buf_len < rec->data_offset
+ || rec->buf_len - rec->data_offset < rec->data_len
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ || rec->cid_len != 0
+#endif
+ )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ data = rec->buf + rec->data_offset;
+ post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
+ data, rec->data_len );
+
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
+
+ if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %" MBEDTLS_PRINTF_SIZET
+ " too large, maximum %" MBEDTLS_PRINTF_SIZET,
+ rec->data_len,
+ (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ /* The following two code paths implement the (D)TLSInnerPlaintext
+ * structure present in TLS 1.3 and DTLS 1.2 + CID.
+ *
+ * See ssl_build_inner_plaintext() for more information.
+ *
+ * Note that this changes `rec->data_len`, and hence
+ * `post_avail` needs to be recalculated afterwards.
+ *
+ * Note also that the two code paths cannot occur simultaneously
+ * since they apply to different versions of the protocol. There
+ * is hence no risk of double-addition of the inner plaintext.
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
+ size_t padding =
+ ssl_compute_padding_length( rec->data_len,
+ MBEDTLS_SSL_TLS1_3_PADDING_GRANULARITY );
+ if( ssl_build_inner_plaintext( data,
+ &rec->data_len,
+ post_avail,
+ rec->type,
+ padding ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ rec->type = MBEDTLS_SSL_MSG_APPLICATION_DATA;
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /*
+ * Add CID information
+ */
+ rec->cid_len = transform->out_cid_len;
+ memcpy( rec->cid, transform->out_cid, transform->out_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len );
+
+ if( rec->cid_len != 0 )
+ {
+ size_t padding =
+ ssl_compute_padding_length( rec->data_len,
+ MBEDTLS_SSL_CID_PADDING_GRANULARITY );
+ /*
+ * Wrap plaintext into DTLSInnerPlaintext structure.
+ * See ssl_build_inner_plaintext() for more information.
+ *
+ * Note that this changes `rec->data_len`, and hence
+ * `post_avail` needs to be recalculated afterwards.
+ */
+ if( ssl_build_inner_plaintext( data,
+ &rec->data_len,
+ post_avail,
+ rec->type,
+ padding ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ rec->type = MBEDTLS_SSL_MSG_CID;
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
+
+ /*
+ * Add MAC before if needed
+ */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( mode == MBEDTLS_MODE_STREAM ||
+ ( mode == MBEDTLS_MODE_CBC
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ && transform->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
+#endif
+ ) )
+ {
+ if( post_avail < transform->maclen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ unsigned char mac[SSL3_MAC_MAX_BYTES];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ ret = ssl_mac( &transform->md_ctx_enc, transform->mac_enc,
+ data, rec->data_len, rec->ctr, rec->type, mac );
+ if( ret == 0 )
+ memcpy( data + rec->data_len, mac, transform->maclen );
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ {
+ unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ add_data, add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+ if( ret != 0 )
+ goto hmac_failed_etm_disabled;
+
+ memcpy( data + rec->data_len, mac, transform->maclen );
+
+ hmac_failed_etm_disabled:
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", data + rec->data_len,
+ transform->maclen );
+
+ rec->data_len += transform->maclen;
+ post_avail -= transform->maclen;
+ auth_done++;
+ }
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+
+ /*
+ * Encrypt
+ */
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+ if( mode == MBEDTLS_MODE_STREAM )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t olen;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including %d bytes of padding",
+ rec->data_len, 0 ) );
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc, transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+ if( mode == MBEDTLS_MODE_GCM ||
+ mode == MBEDTLS_MODE_CCM ||
+ mode == MBEDTLS_MODE_CHACHAPOLY )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char iv[12];
+ unsigned char *dynamic_iv;
+ size_t dynamic_iv_len;
+ int dynamic_iv_is_explicit =
+ ssl_transform_aead_dynamic_iv_is_explicit( transform );
+
+ /* Check that there's space for the authentication tag. */
+ if( post_avail < transform->taglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ /*
+ * Build nonce for AEAD encryption.
+ *
+ * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
+ * part of the IV is prepended to the ciphertext and
+ * can be chosen freely - in particular, it need not
+ * agree with the record sequence number.
+ * However, since ChaChaPoly as well as all AEAD modes
+ * in TLS 1.3 use the record sequence number as the
+ * dynamic part of the nonce, we uniformly use the
+ * record sequence number here in all cases.
+ */
+ dynamic_iv = rec->ctr;
+ dynamic_iv_len = sizeof( rec->ctr );
+
+ ssl_build_record_nonce( iv, sizeof( iv ),
+ transform->iv_enc,
+ transform->fixed_ivlen,
+ dynamic_iv,
+ dynamic_iv_len );
+
+ /*
+ * Build additional data for AEAD encryption.
+ * This depends on the TLS version.
+ */
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
+ iv, transform->ivlen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
+ dynamic_iv,
+ dynamic_iv_is_explicit ? dynamic_iv_len : 0 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
+ add_data, add_data_len );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including 0 bytes of padding",
+ rec->data_len ) );
+
+ /*
+ * Encrypt and authenticate
+ */
+
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &transform->cipher_ctx_enc,
+ iv, transform->ivlen,
+ add_data, add_data_len,
+ data, rec->data_len, /* src */
+ data, rec->buf_len - (data - rec->buf), /* dst */
+ &rec->data_len,
+ transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
+ return( ret );
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
+ data + rec->data_len - transform->taglen,
+ transform->taglen );
+ /* Account for authentication tag. */
+ post_avail -= transform->taglen;
+
+ /*
+ * Prefix record content with dynamic IV in case it is explicit.
+ */
+ if( dynamic_iv_is_explicit != 0 )
+ {
+ if( rec->data_offset < dynamic_iv_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( data - dynamic_iv_len, dynamic_iv, dynamic_iv_len );
+ rec->data_offset -= dynamic_iv_len;
+ rec->data_len += dynamic_iv_len;
+ }
+
+ auth_done++;
+ }
+ else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
+ if( mode == MBEDTLS_MODE_CBC )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t padlen, i;
+ size_t olen;
+
+ /* Currently we're always using minimal padding
+ * (up to 255 bytes would be allowed). */
+ padlen = transform->ivlen - ( rec->data_len + 1 ) % transform->ivlen;
+ if( padlen == transform->ivlen )
+ padlen = 0;
+
+ /* Check there's enough space in the buffer for the padding. */
+ if( post_avail < padlen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ for( i = 0; i <= padlen; i++ )
+ data[rec->data_len + i] = (unsigned char) padlen;
+
+ rec->data_len += padlen + 1;
+ post_avail -= padlen + 1;
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ /*
+ * Prepend per-record IV for block cipher in TLS v1.1 and up as per
+ * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
+ */
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ if( f_rng == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "No PRNG provided to encrypt_record routine" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( rec->data_offset < transform->ivlen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ /*
+ * Generate IV
+ */
+ ret = f_rng( p_rng, transform->iv_enc, transform->ivlen );
+ if( ret != 0 )
+ return( ret );
+
+ memcpy( data - transform->ivlen, transform->iv_enc,
+ transform->ivlen );
+
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %" MBEDTLS_PRINTF_SIZET ", "
+ "including %" MBEDTLS_PRINTF_SIZET
+ " bytes of IV and %" MBEDTLS_PRINTF_SIZET " bytes of padding",
+ rec->data_len, transform->ivlen,
+ padlen + 1 ) );
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1
+ */
+ memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
+ transform->ivlen );
+ }
+ else
+#endif
+ {
+ data -= transform->ivlen;
+ rec->data_offset -= transform->ivlen;
+ rec->data_len += transform->ivlen;
+ }
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( auth_done == 0 )
+ {
+ unsigned char mac[MBEDTLS_SSL_MAC_ADD];
+
+ /*
+ * MAC(MAC_write_key, seq_num +
+ * TLSCipherText.type +
+ * TLSCipherText.version +
+ * length_of( (IV +) ENC(...) ) +
+ * IV + // except for TLS 1.0
+ * ENC(content + padding + padding_length));
+ */
+
+ if( post_avail < transform->maclen)
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Buffer provided for encrypted record not large enough" ) );
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+ }
+
+ ssl_extract_add_data_from_record( add_data, &add_data_len,
+ rec, transform->minor_ver );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
+ add_data_len );
+
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data,
+ add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_enc,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_enc );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+
+ memcpy( data + rec->data_len, mac, transform->maclen );
+
+ rec->data_len += transform->maclen;
+ post_avail -= transform->maclen;
+ auth_done++;
+
+ hmac_failed_etm_enabled:
+ mbedtls_platform_zeroize( mac, transform->maclen );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+ }
+ else
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Make extra sure authentication was performed, exactly once */
+ if( auth_done != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
+ mbedtls_ssl_transform *transform,
+ mbedtls_record *rec )
+{
+ size_t olen;
+ mbedtls_cipher_mode_t mode;
+ int ret, auth_done = 0;
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ size_t padlen = 0, correct = 1;
+#endif
+ unsigned char* data;
+ unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ];
+ size_t add_data_len;
+
+#if !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for debug */
+ ((void) ssl);
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
+ if( rec == NULL ||
+ rec->buf == NULL ||
+ rec->buf_len < rec->data_offset ||
+ rec->buf_len - rec->data_offset < rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to decrypt_buf" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ data = rec->buf + rec->data_offset;
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /*
+ * Match record's CID with incoming CID.
+ */
+ if( rec->cid_len != transform->in_cid_len ||
+ memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_CID );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
+ if( mode == MBEDTLS_MODE_STREAM )
+ {
+ padlen = 0;
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
+ transform->iv_dec,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
+ if( mode == MBEDTLS_MODE_GCM ||
+ mode == MBEDTLS_MODE_CCM ||
+ mode == MBEDTLS_MODE_CHACHAPOLY )
+ {
+ unsigned char iv[12];
+ unsigned char *dynamic_iv;
+ size_t dynamic_iv_len;
+
+ /*
+ * Extract dynamic part of nonce for AEAD decryption.
+ *
+ * Note: In the case of CCM and GCM in TLS 1.2, the dynamic
+ * part of the IV is prepended to the ciphertext and
+ * can be chosen freely - in particular, it need not
+ * agree with the record sequence number.
+ */
+ dynamic_iv_len = sizeof( rec->ctr );
+ if( ssl_transform_aead_dynamic_iv_is_explicit( transform ) == 1 )
+ {
+ if( rec->data_len < dynamic_iv_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ " ) < explicit_iv_len (%" MBEDTLS_PRINTF_SIZET ") ",
+ rec->data_len,
+ dynamic_iv_len ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ dynamic_iv = data;
+
+ data += dynamic_iv_len;
+ rec->data_offset += dynamic_iv_len;
+ rec->data_len -= dynamic_iv_len;
+ }
+ else
+ {
+ dynamic_iv = rec->ctr;
+ }
+
+ /* Check that there's space for the authentication tag. */
+ if( rec->data_len < transform->taglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < taglen (%" MBEDTLS_PRINTF_SIZET ") ",
+ rec->data_len,
+ transform->taglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ rec->data_len -= transform->taglen;
+
+ /*
+ * Prepare nonce from dynamic and static parts.
+ */
+ ssl_build_record_nonce( iv, sizeof( iv ),
+ transform->iv_dec,
+ transform->fixed_ivlen,
+ dynamic_iv,
+ dynamic_iv_len );
+
+ /*
+ * Build additional data for AEAD encryption.
+ * This depends on the TLS version.
+ */
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD",
+ add_data, add_data_len );
+
+ /* Because of the check above, we know that there are
+ * explicit_iv_len Bytes preceeding data, and taglen
+ * bytes following data + data_len. This justifies
+ * the debug message and the invocation of
+ * mbedtls_cipher_auth_decrypt() below. */
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", data + rec->data_len,
+ transform->taglen );
+
+ /*
+ * Decrypt and authenticate
+ */
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &transform->cipher_ctx_dec,
+ iv, transform->ivlen,
+ add_data, add_data_len,
+ data, rec->data_len + transform->taglen, /* src */
+ data, rec->buf_len - (data - rec->buf), &olen, /* dst */
+ transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
+
+ if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+
+ return( ret );
+ }
+ auth_done++;
+
+ /* Double-check that AEAD decryption doesn't change content length. */
+ if( olen != rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+ else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
+#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
+ if( mode == MBEDTLS_MODE_CBC )
+ {
+ size_t minlen = 0;
+
+ /*
+ * Check immediate ciphertext sanity
+ */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /* The ciphertext is prefixed with the CBC IV. */
+ minlen += transform->ivlen;
+ }
+#endif
+
+ /* Size considerations:
+ *
+ * - The CBC cipher text must not be empty and hence
+ * at least of size transform->ivlen.
+ *
+ * Together with the potential IV-prefix, this explains
+ * the first of the two checks below.
+ *
+ * - The record must contain a MAC, either in plain or
+ * encrypted, depending on whether Encrypt-then-MAC
+ * is used or not.
+ * - If it is, the message contains the IV-prefix,
+ * the CBC ciphertext, and the MAC.
+ * - If it is not, the padded plaintext, and hence
+ * the CBC ciphertext, has at least length maclen + 1
+ * because there is at least the padding length byte.
+ *
+ * As the CBC ciphertext is not empty, both cases give the
+ * lower bound minlen + maclen + 1 on the record size, which
+ * we test for in the second check below.
+ */
+ if( rec->data_len < minlen + transform->ivlen ||
+ rec->data_len < minlen + transform->maclen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < max( ivlen(%" MBEDTLS_PRINTF_SIZET
+ "), maclen (%" MBEDTLS_PRINTF_SIZET ") "
+ "+ 1 ) ( + expl IV )", rec->data_len,
+ transform->ivlen,
+ transform->maclen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+
+ /*
+ * Authenticate before decrypt if enabled
+ */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( transform->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+ {
+ unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
+
+ /* Update data_len in tandem with add_data.
+ *
+ * The subtraction is safe because of the previous check
+ * data_len >= minlen + maclen + 1.
+ *
+ * Afterwards, we know that data + data_len is followed by at
+ * least maclen Bytes, which justifies the call to
+ * mbedtls_ct_memcmp() below.
+ *
+ * Further, we still know that data_len > minlen */
+ rec->data_len -= transform->maclen;
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+ /* Calculate expected MAC. */
+ MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data,
+ add_data_len );
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data,
+ add_data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_update( &transform->md_ctx_dec,
+ data, rec->data_len );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+ ret = mbedtls_md_hmac_reset( &transform->md_ctx_dec );
+ if( ret != 0 )
+ goto hmac_failed_etm_enabled;
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", data + rec->data_len,
+ transform->maclen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
+ transform->maclen );
+
+ /* Compare expected MAC with MAC at the end of the record. */
+ if( mbedtls_ct_memcmp( data + rec->data_len, mac_expect,
+ transform->maclen ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+ ret = MBEDTLS_ERR_SSL_INVALID_MAC;
+ goto hmac_failed_etm_enabled;
+ }
+ auth_done++;
+
+ hmac_failed_etm_enabled:
+ mbedtls_platform_zeroize( mac_expect, transform->maclen );
+ if( ret != 0 )
+ {
+ if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+ /*
+ * Check length sanity
+ */
+
+ /* We know from above that data_len > minlen >= 0,
+ * so the following check in particular implies that
+ * data_len >= minlen + ivlen ( = minlen or 2 * minlen ). */
+ if( rec->data_len % transform->ivlen != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") %% ivlen (%" MBEDTLS_PRINTF_SIZET ") != 0",
+ rec->data_len, transform->ivlen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ /*
+ * Initialize for prepended IV for block cipher in TLS v1.1 and up
+ */
+ if( transform->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /* Safe because data_len >= minlen + ivlen = 2 * ivlen. */
+ memcpy( transform->iv_dec, data, transform->ivlen );
+
+ data += transform->ivlen;
+ rec->data_offset += transform->ivlen;
+ rec->data_len -= transform->ivlen;
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ /* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
+
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
+ transform->iv_dec, transform->ivlen,
+ data, rec->data_len, data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+
+ /* Double-check that length hasn't changed during decryption. */
+ if( rec->data_len != olen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ {
+ /*
+ * Save IV in SSL3 and TLS1, where CBC decryption of consecutive
+ * records is equivalent to CBC decryption of the concatenation
+ * of the records; in other words, IVs are maintained across
+ * record decryptions.
+ */
+ memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
+ transform->ivlen );
+ }
+#endif
+
+ /* Safe since data_len >= minlen + maclen + 1, so after having
+ * subtracted at most minlen and maclen up to this point,
+ * data_len > 0 (because of data_len % ivlen == 0, it's actually
+ * >= ivlen ). */
+ padlen = data[rec->data_len - 1];
+
+ if( auth_done == 1 )
+ {
+ const size_t mask = mbedtls_ct_size_mask_ge(
+ rec->data_len,
+ padlen + 1 );
+ correct &= mask;
+ padlen &= mask;
+ }
+ else
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ if( rec->data_len < transform->maclen + padlen + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%" MBEDTLS_PRINTF_SIZET
+ ") < maclen (%" MBEDTLS_PRINTF_SIZET
+ ") + padlen (%" MBEDTLS_PRINTF_SIZET ")",
+ rec->data_len,
+ transform->maclen,
+ padlen + 1 ) );
+ }
+#endif
+
+ const size_t mask = mbedtls_ct_size_mask_ge(
+ rec->data_len,
+ transform->maclen + padlen + 1 );
+ correct &= mask;
+ padlen &= mask;
+ }
+
+ padlen++;
+
+ /* Regardless of the validity of the padding,
+ * we have data_len >= padlen here. */
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* This is the SSL 3.0 path, we don't have to worry about Lucky
+ * 13, because there's a strictly worse padding attack built in
+ * the protocol (known as part of POODLE), so we don't care if the
+ * code is not constant-time, in particular branches are OK. */
+ if( padlen > transform->ivlen )
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %" MBEDTLS_PRINTF_SIZET ", "
+ "should be no more than %" MBEDTLS_PRINTF_SIZET,
+ padlen, transform->ivlen ) );
+#endif
+ correct = 0;
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* The padding check involves a series of up to 256
+ * consecutive memory reads at the end of the record
+ * plaintext buffer. In order to hide the length and
+ * validity of the padding, always perform exactly
+ * `min(256,plaintext_len)` reads (but take into account
+ * only the last `padlen` bytes for the padding check). */
+ size_t pad_count = 0;
+ volatile unsigned char* const check = data;
+
+ /* Index of first padding byte; it has been ensured above
+ * that the subtraction is safe. */
+ size_t const padding_idx = rec->data_len - padlen;
+ size_t const num_checks = rec->data_len <= 256 ? rec->data_len : 256;
+ size_t const start_idx = rec->data_len - num_checks;
+ size_t idx;
+
+ for( idx = start_idx; idx < rec->data_len; idx++ )
+ {
+ /* pad_count += (idx >= padding_idx) &&
+ * (check[idx] == padlen - 1);
+ */
+ const size_t mask = mbedtls_ct_size_mask_ge( idx, padding_idx );
+ const size_t equal = mbedtls_ct_size_bool_eq( check[idx],
+ padlen - 1 );
+ pad_count += mask & equal;
+ }
+ correct &= mbedtls_ct_size_bool_eq( pad_count, padlen );
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ if( padlen > 0 && correct == 0 )
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
+#endif
+ padlen &= mbedtls_ct_size_mask( correct );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* If the padding was found to be invalid, padlen == 0
+ * and the subtraction is safe. If the padding was found valid,
+ * padlen hasn't been changed and the previous assertion
+ * data_len >= padlen still holds. */
+ rec->data_len -= padlen;
+ }
+ else
+#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
+ data, rec->data_len );
+#endif
+
+ /*
+ * Authenticate if not done yet.
+ * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
+ */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( auth_done == 0 )
+ {
+ unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
+ unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
+
+ /* If the initial value of padlen was such that
+ * data_len < maclen + padlen + 1, then padlen
+ * got reset to 1, and the initial check
+ * data_len >= minlen + maclen + 1
+ * guarantees that at this point we still
+ * have at least data_len >= maclen.
+ *
+ * If the initial value of padlen was such that
+ * data_len >= maclen + padlen + 1, then we have
+ * subtracted either padlen + 1 (if the padding was correct)
+ * or 0 (if the padding was incorrect) since then,
+ * hence data_len >= maclen in any case.
+ */
+ rec->data_len -= transform->maclen;
+ ssl_extract_add_data_from_record( add_data, &add_data_len, rec,
+ transform->minor_ver );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ ret = ssl_mac( &transform->md_ctx_dec,
+ transform->mac_dec,
+ data, rec->data_len,
+ rec->ctr, rec->type,
+ mac_expect );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
+ goto hmac_failed_etm_disabled;
+ }
+ memcpy( mac_peer, data + rec->data_len, transform->maclen );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( transform->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /*
+ * The next two sizes are the minimum and maximum values of
+ * data_len over all padlen values.
+ *
+ * They're independent of padlen, since we previously did
+ * data_len -= padlen.
+ *
+ * Note that max_len + maclen is never more than the buffer
+ * length, as we previously did in_msglen -= maclen too.
+ */
+ const size_t max_len = rec->data_len + padlen;
+ const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
+
+ ret = mbedtls_ct_hmac( &transform->md_ctx_dec,
+ add_data, add_data_len,
+ data, rec->data_len, min_len, max_len,
+ mac_expect );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ct_hmac", ret );
+ goto hmac_failed_etm_disabled;
+ }
+
+ mbedtls_ct_memcpy_offset( mac_peer, data,
+ rec->data_len,
+ min_len, max_len,
+ transform->maclen );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, transform->maclen );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", mac_peer, transform->maclen );
+#endif
+
+ if( mbedtls_ct_memcmp( mac_peer, mac_expect,
+ transform->maclen ) != 0 )
+ {
+#if defined(MBEDTLS_SSL_DEBUG_ALL)
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
+#endif
+ correct = 0;
+ }
+ auth_done++;
+
+ hmac_failed_etm_disabled:
+ mbedtls_platform_zeroize( mac_peer, transform->maclen );
+ mbedtls_platform_zeroize( mac_expect, transform->maclen );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ /*
+ * Finally check the correct flag
+ */
+ if( correct == 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+
+ /* Make extra sure authentication was performed, exactly once */
+ if( auth_done != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
+ /* Remove inner padding and infer true content type. */
+ ret = ssl_parse_inner_plaintext( data, &rec->data_len,
+ &rec->type );
+
+ if( ret != 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( rec->cid_len != 0 )
+ {
+ ret = ssl_parse_inner_plaintext( data, &rec->data_len,
+ &rec->type );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
+
+ return( 0 );
+}
+
+#undef MAC_NONE
+#undef MAC_PLAINTEXT
+#undef MAC_CIPHERTEXT
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+/*
+ * Compression/decompression functions
+ */
+static int ssl_compress_buf( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *msg_post = ssl->out_msg;
+ ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
+ size_t len_pre = ssl->out_msglen;
+ unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
+
+ if( len_pre == 0 )
+ return( 0 );
+
+ memcpy( msg_pre, ssl->out_msg, len_pre );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->out_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
+ ssl->out_msg, ssl->out_msglen );
+
+ ssl->transform_out->ctx_deflate.next_in = msg_pre;
+ ssl->transform_out->ctx_deflate.avail_in = len_pre;
+ ssl->transform_out->ctx_deflate.next_out = msg_post;
+ ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written;
+
+ ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
+ if( ret != Z_OK )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
+ return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ }
+
+ ssl->out_msglen = out_buf_len -
+ ssl->transform_out->ctx_deflate.avail_out - bytes_written;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->out_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
+ ssl->out_msg, ssl->out_msglen );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
+
+ return( 0 );
+}
+
+static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *msg_post = ssl->in_msg;
+ ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
+ size_t len_pre = ssl->in_msglen;
+ unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
+
+ if( len_pre == 0 )
+ return( 0 );
+
+ memcpy( msg_pre, ssl->in_msg, len_pre );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->in_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
+ ssl->in_msg, ssl->in_msglen );
+
+ ssl->transform_in->ctx_inflate.next_in = msg_pre;
+ ssl->transform_in->ctx_inflate.avail_in = len_pre;
+ ssl->transform_in->ctx_inflate.next_out = msg_post;
+ ssl->transform_in->ctx_inflate.avail_out = in_buf_len - header_bytes;
+
+ ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
+ if( ret != Z_OK )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
+ return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ }
+
+ ssl->in_msglen = in_buf_len -
+ ssl->transform_in->ctx_inflate.avail_out - header_bytes;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %" MBEDTLS_PRINTF_SIZET ", ",
+ ssl->in_msglen ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
+ ssl->in_msg, ssl->in_msglen );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+/*
+ * Fill the input message buffer by appending data to it.
+ * The amount of data already fetched is in ssl->in_left.
+ *
+ * If we return 0, is it guaranteed that (at least) nb_want bytes are
+ * available (from this read and/or a previous one). Otherwise, an error code
+ * is returned (possibly EOF or WANT_READ).
+ *
+ * With stream transport (TLS) on success ssl->in_left == nb_want, but
+ * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
+ * since we always read a whole datagram at once.
+ *
+ * For DTLS, it is up to the caller to set ssl->next_record_offset when
+ * they're done reading a record.
+ */
+int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
+
+ if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+ "or mbedtls_ssl_set_bio()" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ uint32_t timeout;
+
+ /*
+ * The point is, we need to always read a full datagram at once, so we
+ * sometimes read more then requested, and handle the additional data.
+ * It could be the rest of the current record (while fetching the
+ * header) and/or some other records in the same datagram.
+ */
+
+ /*
+ * Move to the next record in the already read datagram if applicable
+ */
+ if( ssl->next_record_offset != 0 )
+ {
+ if( ssl->in_left < ssl->next_record_offset )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->in_left -= ssl->next_record_offset;
+
+ if( ssl->in_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %"
+ MBEDTLS_PRINTF_SIZET,
+ ssl->next_record_offset ) );
+ memmove( ssl->in_hdr,
+ ssl->in_hdr + ssl->next_record_offset,
+ ssl->in_left );
+ }
+
+ ssl->next_record_offset = 0;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+
+ /*
+ * Done if we already have enough data.
+ */
+ if( nb_want <= ssl->in_left)
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+ return( 0 );
+ }
+
+ /*
+ * A record can't be split across datagrams. If we need to read but
+ * are not at the beginning of a new record, the caller did something
+ * wrong.
+ */
+ if( ssl->in_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Don't even try to read if time's out already.
+ * This avoids by-passing the timer when repeatedly receiving messages
+ * that will end up being dropped.
+ */
+ if( mbedtls_ssl_check_timer( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
+ ret = MBEDTLS_ERR_SSL_TIMEOUT;
+ }
+ else
+ {
+ len = in_buf_len - ( ssl->in_hdr - ssl->in_buf );
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ timeout = ssl->handshake->retransmit_timeout;
+ else
+ timeout = ssl->conf->read_timeout;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %lu ms", (unsigned long) timeout ) );
+
+ if( ssl->f_recv_timeout != NULL )
+ ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
+ timeout );
+ else
+ ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+ if( ret == 0 )
+ return( MBEDTLS_ERR_SSL_CONN_EOF );
+ }
+
+ if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ssl_double_retransmit_timeout( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
+ return( MBEDTLS_ERR_SSL_TIMEOUT );
+ }
+
+ if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+ else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
+ ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+ }
+
+ if( ret < 0 )
+ return( ret );
+
+ ssl->in_left = ret;
+ }
+ else
+#endif
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+
+ while( ssl->in_left < nb_want )
+ {
+ len = nb_want - ssl->in_left;
+
+ if( mbedtls_ssl_check_timer( ssl ) != 0 )
+ ret = MBEDTLS_ERR_SSL_TIMEOUT;
+ else
+ {
+ if( ssl->f_recv_timeout != NULL )
+ {
+ ret = ssl->f_recv_timeout( ssl->p_bio,
+ ssl->in_hdr + ssl->in_left, len,
+ ssl->conf->read_timeout );
+ }
+ else
+ {
+ ret = ssl->f_recv( ssl->p_bio,
+ ssl->in_hdr + ssl->in_left, len );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %" MBEDTLS_PRINTF_SIZET
+ ", nb_want: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_left, nb_want ) );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
+
+ if( ret == 0 )
+ return( MBEDTLS_ERR_SSL_CONN_EOF );
+
+ if( ret < 0 )
+ return( ret );
+
+ 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 %" MBEDTLS_PRINTF_SIZET " were requested",
+ ret, len ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->in_left += ret;
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
+
+ return( 0 );
+}
+
+/*
+ * Flush any data not yet written
+ */
+int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *buf;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
+
+ if( ssl->f_send == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
+ "or mbedtls_ssl_set_bio()" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ /* Avoid incrementing counter if data is flushed */
+ if( ssl->out_left == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+ return( 0 );
+ }
+
+ while( ssl->out_left > 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %" MBEDTLS_PRINTF_SIZET
+ ", out_left: %" MBEDTLS_PRINTF_SIZET,
+ mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
+
+ buf = ssl->out_hdr - ssl->out_left;
+ ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
+
+ if( ret <= 0 )
+ return( ret );
+
+ 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 %" MBEDTLS_PRINTF_SIZET " bytes were sent",
+ ret, ssl->out_left ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ ssl->out_left -= ret;
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_hdr = ssl->out_buf;
+ }
+ else
+#endif
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ }
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
+
+ return( 0 );
+}
+
+/*
+ * Functions to handle the DTLS retransmission state machine
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+/*
+ * Append current handshake message to current outgoing flight
+ */
+static int ssl_flight_append( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_flight_item *msg;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
+ ssl->out_msg, ssl->out_msglen );
+
+ /* Allocate space for current message */
+ if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
+ sizeof( mbedtls_ssl_flight_item ) ) );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+
+ if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %" MBEDTLS_PRINTF_SIZET " bytes failed",
+ ssl->out_msglen ) );
+ mbedtls_free( msg );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+
+ /* Copy current handshake message with headers */
+ memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
+ msg->len = ssl->out_msglen;
+ msg->type = ssl->out_msgtype;
+ msg->next = NULL;
+
+ /* Append to the current flight */
+ if( ssl->handshake->flight == NULL )
+ ssl->handshake->flight = msg;
+ else
+ {
+ mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
+ while( cur->next != NULL )
+ cur = cur->next;
+ cur->next = msg;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
+ return( 0 );
+}
+
+/*
+ * Free the current flight of handshake messages
+ */
+void mbedtls_ssl_flight_free( mbedtls_ssl_flight_item *flight )
+{
+ mbedtls_ssl_flight_item *cur = flight;
+ mbedtls_ssl_flight_item *next;
+
+ while( cur != NULL )
+ {
+ next = cur->next;
+
+ mbedtls_free( cur->p );
+ mbedtls_free( cur );
+
+ cur = next;
+ }
+}
+
+/*
+ * Swap transform_out and out_ctr with the alternative ones
+ */
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_transform *tmp_transform;
+ unsigned char tmp_out_ctr[8];
+
+ if( ssl->transform_out == ssl->handshake->alt_transform_out )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
+ return( 0 );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
+
+ /* Swap transforms */
+ tmp_transform = ssl->transform_out;
+ ssl->transform_out = ssl->handshake->alt_transform_out;
+ ssl->handshake->alt_transform_out = tmp_transform;
+
+ /* Swap epoch + sequence_number */
+ memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
+ memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
+ memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
+
+ /* Adjust to the newly activated transform */
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_activate != NULL )
+ {
+ int ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
+ return( 0 );
+}
+
+/*
+ * Retransmit the current flight of messages.
+ */
+int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
+
+ ret = mbedtls_ssl_flight_transmit( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
+
+ return( ret );
+}
+
+/*
+ * Transmit or retransmit the current flight of messages.
+ *
+ * Need to remember the current message in case flush_output returns
+ * WANT_WRITE, causing us to exit this function and come back later.
+ * This function must be called until state is no longer SENDING.
+ */
+int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
+
+ if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
+
+ ssl->handshake->cur_msg = ssl->handshake->flight;
+ ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
+ }
+
+ while( ssl->handshake->cur_msg != NULL )
+ {
+ size_t max_frag_len;
+ const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
+
+ int const is_finished =
+ ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
+
+ uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
+ SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
+
+ /* Swap epochs before sending Finished: we can't do it after
+ * sending ChangeCipherSpec, in case write returns WANT_READ.
+ * Must be done before copying, may change out_msg pointer */
+ if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ max_frag_len = (size_t) ret;
+
+ /* CCS is copied as is, while HS messages may need fragmentation */
+ if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ if( max_frag_len == 0 )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+
+ memcpy( ssl->out_msg, cur->p, cur->len );
+ ssl->out_msglen = cur->len;
+ ssl->out_msgtype = cur->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += cur->len;
+ }
+ else
+ {
+ const unsigned char * const p = ssl->handshake->cur_msg_p;
+ const size_t hs_len = cur->len - 12;
+ const size_t frag_off = p - ( cur->p + 12 );
+ const size_t rem_len = hs_len - frag_off;
+ size_t cur_hs_frag_len, max_hs_frag_len;
+
+ if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
+ {
+ if( is_finished )
+ {
+ ret = ssl_swap_epochs( ssl );
+ if( ret != 0 )
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ continue;
+ }
+ max_hs_frag_len = max_frag_len - 12;
+
+ cur_hs_frag_len = rem_len > max_hs_frag_len ?
+ max_hs_frag_len : rem_len;
+
+ if( frag_off == 0 && cur_hs_frag_len != hs_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
+ (unsigned) cur_hs_frag_len,
+ (unsigned) max_hs_frag_len ) );
+ }
+
+ /* Messages are stored with handshake headers as if not fragmented,
+ * copy beginning of headers then fill fragmentation fields.
+ * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
+ memcpy( ssl->out_msg, cur->p, 6 );
+
+ ssl->out_msg[6] = MBEDTLS_BYTE_2( frag_off );
+ ssl->out_msg[7] = MBEDTLS_BYTE_1( frag_off );
+ ssl->out_msg[8] = MBEDTLS_BYTE_0( frag_off );
+
+ ssl->out_msg[ 9] = MBEDTLS_BYTE_2( cur_hs_frag_len );
+ ssl->out_msg[10] = MBEDTLS_BYTE_1( cur_hs_frag_len );
+ ssl->out_msg[11] = MBEDTLS_BYTE_0( cur_hs_frag_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
+
+ /* Copy the handshake message content and set records fields */
+ memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
+ ssl->out_msglen = cur_hs_frag_len + 12;
+ ssl->out_msgtype = cur->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += cur_hs_frag_len;
+ }
+
+ /* If done with the current message move to the next one if any */
+ if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
+ {
+ if( cur->next != NULL )
+ {
+ ssl->handshake->cur_msg = cur->next;
+ ssl->handshake->cur_msg_p = cur->next->p + 12;
+ }
+ else
+ {
+ ssl->handshake->cur_msg = NULL;
+ ssl->handshake->cur_msg_p = NULL;
+ }
+ }
+
+ /* Actually send the message out */
+ if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ /* Update state and set timer */
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ else
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+ mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
+
+ return( 0 );
+}
+
+/*
+ * To be called when the last message of an incoming flight is received.
+ */
+void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
+{
+ /* We won't need to resend that one any more */
+ mbedtls_ssl_flight_free( ssl->handshake->flight );
+ ssl->handshake->flight = NULL;
+ ssl->handshake->cur_msg = NULL;
+
+ /* The next incoming flight will start with this msg_seq */
+ ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
+
+ /* We don't want to remember CCS's across flight boundaries. */
+ ssl->handshake->buffering.seen_ccs = 0;
+
+ /* Clear future message buffering structure. */
+ mbedtls_ssl_buffering_free( ssl );
+
+ /* Cancel timer */
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ }
+ else
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
+}
+
+/*
+ * To be called when the last message of an outgoing flight is send.
+ */
+void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
+{
+ ssl_reset_retransmit_timeout( ssl );
+ mbedtls_ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ }
+ else
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/*
+ * Handshake layer functions
+ */
+
+/*
+ * Write (DTLS: or queue) current handshake (including CCS) message.
+ *
+ * - fill in handshake headers
+ * - update handshake checksum
+ * - DTLS: save message for resending
+ * - then pass to the record layer
+ *
+ * DTLS: except for HelloRequest, messages are only queued, and will only be
+ * actually sent when calling flight_transmit() or resend().
+ *
+ * Inputs:
+ * - ssl->out_msglen: 4 + actual handshake message len
+ * (4 is the size of handshake headers for TLS)
+ * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
+ * - ssl->out_msg + 4: the handshake message body
+ *
+ * Outputs, ie state before passing to flight_append() or write_record():
+ * - ssl->out_msglen: the length of the record contents
+ * (including handshake headers but excluding record headers)
+ * - ssl->out_msg: the record contents (handshake headers + content)
+ */
+int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const size_t hs_len = ssl->out_msglen - 4;
+ const unsigned char hs_type = ssl->out_msg[0];
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
+
+ /*
+ * Sanity checks
+ */
+ if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ /* In SSLv3, the client might send a NoCertificate alert. */
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
+ if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+ ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+
+ /* Whenever we send anything different from a
+ * HelloRequest we should be in a handshake - double check. */
+ if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
+ ssl->handshake == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->handshake != NULL &&
+ ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+#endif
+
+ /* Double-check that we did not exceed the bounds
+ * of the outgoing record buffer.
+ * This should never fail as the various message
+ * writing functions must obey the bounds of the
+ * outgoing record buffer, but better be safe.
+ *
+ * Note: We deliberately do not check for the MTU or MFL here.
+ */
+ if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
+ "size %" MBEDTLS_PRINTF_SIZET
+ ", maximum %" MBEDTLS_PRINTF_SIZET,
+ ssl->out_msglen,
+ (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Fill handshake headers
+ */
+ if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ ssl->out_msg[1] = MBEDTLS_BYTE_2( hs_len );
+ ssl->out_msg[2] = MBEDTLS_BYTE_1( hs_len );
+ ssl->out_msg[3] = MBEDTLS_BYTE_0( hs_len );
+
+ /*
+ * DTLS has additional fields in the Handshake layer,
+ * between the length field and the actual payload:
+ * uint16 message_seq;
+ * uint24 fragment_offset;
+ * uint24 fragment_length;
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Make room for the additional DTLS fields */
+ if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
+ "size %" MBEDTLS_PRINTF_SIZET ", maximum %" MBEDTLS_PRINTF_SIZET,
+ hs_len,
+ (size_t) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
+ ssl->out_msglen += 8;
+
+ /* Write message_seq and update it, except for HelloRequest */
+ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+ {
+ MBEDTLS_PUT_UINT16_BE( ssl->handshake->out_msg_seq, ssl->out_msg, 4 );
+ ++( ssl->handshake->out_msg_seq );
+ }
+ else
+ {
+ ssl->out_msg[4] = 0;
+ ssl->out_msg[5] = 0;
+ }
+
+ /* Handshake hashes are computed without fragmentation,
+ * so set frag_offset = 0 and frag_len = hs_len for now */
+ memset( ssl->out_msg + 6, 0x00, 3 );
+ memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Update running hashes of handshake messages seen */
+ if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
+ ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
+ }
+
+ /* Either send now, or just save to be sent (and resent) later */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
+ {
+ if( ( ret = ssl_flight_append( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
+ return( ret );
+ }
+ }
+ else
+#endif
+ {
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
+
+ return( 0 );
+}
+
+/*
+ * Record layer functions
+ */
+
+/*
+ * Write current record.
+ *
+ * Uses:
+ * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
+ * - ssl->out_msglen: length of the record content (excl headers)
+ * - ssl->out_msg: record content
+ */
+int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
+{
+ int ret, done = 0;
+ size_t len = ssl->out_msglen;
+ uint8_t flush = force_flush;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->transform_out != NULL &&
+ ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ {
+ if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
+ return( ret );
+ }
+
+ len = ssl->out_msglen;
+ }
+#endif /*MBEDTLS_ZLIB_SUPPORT */
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_write != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
+
+ ret = mbedtls_ssl_hw_record_write( ssl );
+ if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ret == 0 )
+ done = 1;
+ }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+ if( !done )
+ {
+ unsigned i;
+ size_t protected_record_size;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+ /* Skip writing the record content type to after the encryption,
+ * as it may change when using the CID extension. */
+
+ mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+ ssl->conf->transport, ssl->out_hdr + 1 );
+
+ memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
+ MBEDTLS_PUT_UINT16_BE( len, ssl->out_len, 0);
+
+ if( ssl->transform_out != NULL )
+ {
+ mbedtls_record rec;
+
+ rec.buf = ssl->out_iv;
+ rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf );
+ rec.data_len = ssl->out_msglen;
+ rec.data_offset = ssl->out_msg - rec.buf;
+
+ memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
+ mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
+ ssl->conf->transport, rec.ver );
+ rec.type = ssl->out_msgtype;
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* The CID is set by mbedtls_ssl_encrypt_buf(). */
+ rec.cid_len = 0;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec,
+ ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
+ return( ret );
+ }
+
+ if( rec.data_offset != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /* Update the record content type and CID. */
+ ssl->out_msgtype = rec.type;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID )
+ memcpy( ssl->out_cid, rec.cid, rec.cid_len );
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_msglen = len = rec.data_len;
+ MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->out_len, 0 );
+ }
+
+ protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* In case of DTLS, double-check that we don't exceed
+ * the remaining space in the datagram. */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ret = ssl_get_remaining_space_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+
+ if( protected_record_size > (size_t) ret )
+ {
+ /* Should never happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Now write the potentially updated record content type. */
+ ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %u, "
+ "version = [%u:%u], msglen = %" MBEDTLS_PRINTF_SIZET,
+ ssl->out_hdr[0], ssl->out_hdr[1],
+ ssl->out_hdr[2], len ) );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_hdr, protected_record_size );
+
+ ssl->out_left += protected_record_size;
+ ssl->out_hdr += protected_record_size;
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_out );
+
+ for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+ if( ++ssl->cur_out_ctr[i - 1] != 0 )
+ break;
+
+ /* The loop goes to its end iff the counter is wrapping */
+ if( i == mbedtls_ssl_ep_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ flush == SSL_DONT_FORCE_FLUSH )
+ {
+ size_t remaining;
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
+ ret );
+ return( ret );
+ }
+
+ remaining = (size_t) ret;
+ if( remaining == 0 )
+ {
+ flush = SSL_FORCE_FLUSH;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ if( ( flush == SSL_FORCE_FLUSH ) &&
+ ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen < ssl->in_hslen ||
+ memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
+ memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
+ {
+ return( 1 );
+ }
+ return( 0 );
+}
+
+static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[9] << 16 ) |
+ ( ssl->in_msg[10] << 8 ) |
+ ssl->in_msg[11] );
+}
+
+static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[6] << 16 ) |
+ ( ssl->in_msg[7] << 8 ) |
+ ssl->in_msg[8] );
+}
+
+static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
+{
+ uint32_t msg_len, frag_off, frag_len;
+
+ msg_len = ssl_get_hs_total_len( ssl );
+ frag_off = ssl_get_hs_frag_off( ssl );
+ frag_len = ssl_get_hs_frag_len( ssl );
+
+ if( frag_off > msg_len )
+ return( -1 );
+
+ if( frag_len > msg_len - frag_off )
+ return( -1 );
+
+ if( frag_len + 12 > ssl->in_msglen )
+ return( -1 );
+
+ return( 0 );
+}
+
+/*
+ * Mark bits in bitmask (used for DTLS HS reassembly)
+ */
+static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
+{
+ unsigned int start_bits, end_bits;
+
+ start_bits = 8 - ( offset % 8 );
+ if( start_bits != 8 )
+ {
+ size_t first_byte_idx = offset / 8;
+
+ /* Special case */
+ if( len <= start_bits )
+ {
+ for( ; len != 0; len-- )
+ mask[first_byte_idx] |= 1 << ( start_bits - len );
+
+ /* Avoid potential issues with offset or len becoming invalid */
+ return;
+ }
+
+ offset += start_bits; /* Now offset % 8 == 0 */
+ len -= start_bits;
+
+ for( ; start_bits != 0; start_bits-- )
+ mask[first_byte_idx] |= 1 << ( start_bits - 1 );
+ }
+
+ end_bits = len % 8;
+ if( end_bits != 0 )
+ {
+ size_t last_byte_idx = ( offset + len ) / 8;
+
+ len -= end_bits; /* Now len % 8 == 0 */
+
+ for( ; end_bits != 0; end_bits-- )
+ mask[last_byte_idx] |= 1 << ( 8 - end_bits );
+ }
+
+ memset( mask + offset / 8, 0xFF, len / 8 );
+}
+
+/*
+ * Check that bitmask is full
+ */
+static int ssl_bitmask_check( unsigned char *mask, size_t len )
+{
+ size_t i;
+
+ for( i = 0; i < len / 8; i++ )
+ if( mask[i] != 0xFF )
+ return( -1 );
+
+ for( i = 0; i < len % 8; i++ )
+ if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
+ return( -1 );
+
+ return( 0 );
+}
+
+/* msg_len does not include the handshake header */
+static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
+ unsigned add_bitmap )
+{
+ size_t alloc_len;
+
+ alloc_len = 12; /* Handshake header */
+ alloc_len += msg_len; /* Content buffer */
+
+ if( add_bitmap )
+ alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
+
+ return( alloc_len );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
+{
+ return( ( ssl->in_msg[1] << 16 ) |
+ ( ssl->in_msg[2] << 8 ) |
+ ssl->in_msg[3] );
+}
+
+int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
+ " %" MBEDTLS_PRINTF_SIZET ", type = %u, hslen = %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+
+ if( ssl_check_hs_header( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->handshake != NULL &&
+ ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
+ recv_msg_seq != ssl->handshake->in_msg_seq ) ||
+ ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
+ {
+ if( recv_msg_seq > ssl->handshake->in_msg_seq )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
+ recv_msg_seq,
+ ssl->handshake->in_msg_seq ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+
+ /* Retransmit only on last message from previous flight, to avoid
+ * too many retransmissions.
+ * Besides, No sane server ever retransmits HelloVerifyRequest */
+ if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
+ "message_seq = %u, start_of_flight = %u",
+ recv_msg_seq,
+ ssl->handshake->in_flight_start_seq ) );
+
+ if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
+ return( ret );
+ }
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
+ "message_seq = %u, expected = %u",
+ recv_msg_seq,
+ ssl->handshake->in_msg_seq ) );
+ }
+
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+ /* Wait until message completion to increment in_msg_seq */
+
+ /* Message reassembly is handled alongside buffering of future
+ * messages; the commonality is that both handshake fragments and
+ * future messages cannot be forwarded immediately to the
+ * handshake logic layer. */
+ if( ssl_hs_is_proper_fragment( ssl ) == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ /* With TLS we don't handle fragmentation (for now) */
+ if( ssl->in_msglen < ssl->in_hslen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
+
+ return( 0 );
+}
+
+void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
+ {
+ ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
+ }
+
+ /* Handshake message is complete, increment counter */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->handshake != NULL )
+ {
+ unsigned offset;
+ mbedtls_ssl_hs_buffer *hs_buf;
+
+ /* Increment handshake sequence number */
+ hs->in_msg_seq++;
+
+ /*
+ * Clear up handshake buffering and reassembly structure.
+ */
+
+ /* Free first entry */
+ ssl_buffering_free_slot( ssl, 0 );
+
+ /* Shift all other entries */
+ for( offset = 0, hs_buf = &hs->buffering.hs[0];
+ offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
+ offset++, hs_buf++ )
+ {
+ *hs_buf = *(hs_buf + 1);
+ }
+
+ /* Create a fresh last entry */
+ memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+ }
+#endif
+}
+
+/*
+ * DTLS anti-replay: RFC 6347 4.1.2.6
+ *
+ * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
+ * Bit n is set iff record number in_window_top - n has been seen.
+ *
+ * Usually, in_window_top is the last record number seen and the lsb of
+ * in_window is set. The only exception is the initial state (record number 0
+ * not seen yet).
+ */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+void mbedtls_ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
+{
+ ssl->in_window_top = 0;
+ ssl->in_window = 0;
+}
+
+static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
+{
+ return( ( (uint64_t) buf[0] << 40 ) |
+ ( (uint64_t) buf[1] << 32 ) |
+ ( (uint64_t) buf[2] << 24 ) |
+ ( (uint64_t) buf[3] << 16 ) |
+ ( (uint64_t) buf[4] << 8 ) |
+ ( (uint64_t) buf[5] ) );
+}
+
+static int mbedtls_ssl_dtls_record_replay_check( mbedtls_ssl_context *ssl, uint8_t *record_in_ctr )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char *original_in_ctr;
+
+ // save original in_ctr
+ original_in_ctr = ssl->in_ctr;
+
+ // use counter from record
+ ssl->in_ctr = record_in_ctr;
+
+ ret = mbedtls_ssl_dtls_replay_check( (mbedtls_ssl_context const *) ssl );
+
+ // restore the counter
+ ssl->in_ctr = original_in_ctr;
+
+ return ret;
+}
+
+/*
+ * Return 0 if sequence number is acceptable, -1 otherwise
+ */
+int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context const *ssl )
+{
+ uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+ uint64_t bit;
+
+ if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+ return( 0 );
+
+ if( rec_seqnum > ssl->in_window_top )
+ return( 0 );
+
+ bit = ssl->in_window_top - rec_seqnum;
+
+ if( bit >= 64 )
+ return( -1 );
+
+ if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
+ return( -1 );
+
+ return( 0 );
+}
+
+/*
+ * Update replay window on new validated record
+ */
+void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
+{
+ uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
+
+ if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
+ return;
+
+ if( rec_seqnum > ssl->in_window_top )
+ {
+ /* Update window_top and the contents of the window */
+ uint64_t shift = rec_seqnum - ssl->in_window_top;
+
+ if( shift >= 64 )
+ ssl->in_window = 1;
+ else
+ {
+ ssl->in_window <<= shift;
+ ssl->in_window |= 1;
+ }
+
+ ssl->in_window_top = rec_seqnum;
+ }
+ else
+ {
+ /* Mark that number as seen in the current window */
+ uint64_t bit = ssl->in_window_top - rec_seqnum;
+
+ if( bit < 64 ) /* Always true, but be extra sure */
+ ssl->in_window |= (uint64_t) 1 << bit;
+ }
+}
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+/*
+ * Without any SSL context, check if a datagram looks like a ClientHello with
+ * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
+ * Both input and output include full DTLS headers.
+ *
+ * - if cookie is valid, return 0
+ * - if ClientHello looks superficially valid but cookie is not,
+ * fill obuf and set olen, then
+ * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
+ * - otherwise return a specific error code
+ */
+static int ssl_check_dtls_clihlo_cookie(
+ mbedtls_ssl_cookie_write_t *f_cookie_write,
+ mbedtls_ssl_cookie_check_t *f_cookie_check,
+ void *p_cookie,
+ const unsigned char *cli_id, size_t cli_id_len,
+ const unsigned char *in, size_t in_len,
+ unsigned char *obuf, size_t buf_len, size_t *olen )
+{
+ size_t sid_len, cookie_len;
+ unsigned char *p;
+
+ /*
+ * Structure of ClientHello with record and handshake headers,
+ * and expected values. We don't need to check a lot, more checks will be
+ * done when actually parsing the ClientHello - skipping those checks
+ * avoids code duplication and does not make cookie forging any easier.
+ *
+ * 0-0 ContentType type; copied, must be handshake
+ * 1-2 ProtocolVersion version; copied
+ * 3-4 uint16 epoch; copied, must be 0
+ * 5-10 uint48 sequence_number; copied
+ * 11-12 uint16 length; (ignored)
+ *
+ * 13-13 HandshakeType msg_type; (ignored)
+ * 14-16 uint24 length; (ignored)
+ * 17-18 uint16 message_seq; copied
+ * 19-21 uint24 fragment_offset; copied, must be 0
+ * 22-24 uint24 fragment_length; (ignored)
+ *
+ * 25-26 ProtocolVersion client_version; (ignored)
+ * 27-58 Random random; (ignored)
+ * 59-xx SessionID session_id; 1 byte len + sid_len content
+ * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
+ * ...
+ *
+ * Minimum length is 61 bytes.
+ */
+ if( in_len < 61 ||
+ in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
+ in[3] != 0 || in[4] != 0 ||
+ in[19] != 0 || in[20] != 0 || in[21] != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ sid_len = in[59];
+ if( sid_len > in_len - 61 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+ cookie_len = in[60 + sid_len];
+ if( cookie_len > in_len - 60 )
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+
+ if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
+ cli_id, cli_id_len ) == 0 )
+ {
+ /* Valid cookie */
+ return( 0 );
+ }
+
+ /*
+ * If we get here, we've got an invalid cookie, let's prepare HVR.
+ *
+ * 0-0 ContentType type; copied
+ * 1-2 ProtocolVersion version; copied
+ * 3-4 uint16 epoch; copied
+ * 5-10 uint48 sequence_number; copied
+ * 11-12 uint16 length; olen - 13
+ *
+ * 13-13 HandshakeType msg_type; hello_verify_request
+ * 14-16 uint24 length; olen - 25
+ * 17-18 uint16 message_seq; copied
+ * 19-21 uint24 fragment_offset; copied
+ * 22-24 uint24 fragment_length; olen - 25
+ *
+ * 25-26 ProtocolVersion server_version; 0xfe 0xff
+ * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
+ *
+ * Minimum length is 28.
+ */
+ if( buf_len < 28 )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ /* Copy most fields and adapt others */
+ memcpy( obuf, in, 25 );
+ obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
+ obuf[25] = 0xfe;
+ obuf[26] = 0xff;
+
+ /* Generate and write actual cookie */
+ p = obuf + 28;
+ if( f_cookie_write( p_cookie,
+ &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ *olen = p - obuf;
+
+ /* Go back and fill length fields */
+ obuf[27] = (unsigned char)( *olen - 28 );
+
+ obuf[14] = obuf[22] = MBEDTLS_BYTE_2( *olen - 25 );
+ obuf[15] = obuf[23] = MBEDTLS_BYTE_1( *olen - 25 );
+ obuf[16] = obuf[24] = MBEDTLS_BYTE_0( *olen - 25 );
+
+ MBEDTLS_PUT_UINT16_BE( *olen - 13, obuf, 11 );
+
+ return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
+}
+
+/*
+ * Handle possible client reconnect with the same UDP quadruplet
+ * (RFC 6347 Section 4.2.8).
+ *
+ * Called by ssl_parse_record_header() in case we receive an epoch 0 record
+ * that looks like a ClientHello.
+ *
+ * - if the input looks like a ClientHello without cookies,
+ * send back HelloVerifyRequest, then return 0
+ * - if the input looks like a ClientHello with a valid cookie,
+ * reset the session of the current context, and
+ * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
+ * - if anything goes wrong, return a specific error code
+ *
+ * This function is called (through ssl_check_client_reconnect()) when an
+ * unexpected record is found in ssl_get_next_record(), which will discard the
+ * record if we return 0, and bubble up the return value otherwise (this
+ * includes the case of MBEDTLS_ERR_SSL_CLIENT_RECONNECT and of unexpected
+ * errors, and is the right thing to do in both cases).
+ */
+static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+
+ if( ssl->conf->f_cookie_write == NULL ||
+ ssl->conf->f_cookie_check == NULL )
+ {
+ /* If we can't use cookies to verify reachability of the peer,
+ * drop the record. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "no cookie callbacks, "
+ "can't check reconnect validity" ) );
+ return( 0 );
+ }
+
+ ret = ssl_check_dtls_clihlo_cookie(
+ ssl->conf->f_cookie_write,
+ ssl->conf->f_cookie_check,
+ ssl->conf->p_cookie,
+ ssl->cli_id, ssl->cli_id_len,
+ ssl->in_buf, ssl->in_left,
+ ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
+
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
+
+ if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
+ {
+ int send_ret;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_buf, len );
+ /* Don't check write errors as we can't do anything here.
+ * If the error is permanent we'll catch it later,
+ * if it's not, then hopefully it'll work next time. */
+ send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
+ (void) send_ret;
+
+ return( 0 );
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
+ if( ( ret = mbedtls_ssl_session_reset_int( ssl, 1 ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
+ return( ret );
+ }
+
+ return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
+ }
+
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+
+static int ssl_check_record_type( uint8_t record_type )
+{
+ if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE &&
+ record_type != MBEDTLS_SSL_MSG_ALERT &&
+ record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
+ record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ return( 0 );
+}
+
+/*
+ * ContentType type;
+ * ProtocolVersion version;
+ * uint16 epoch; // DTLS only
+ * uint48 sequence_number; // DTLS only
+ * uint16 length;
+ *
+ * Return 0 if header looks sane (and, for DTLS, the record is expected)
+ * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
+ * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
+ *
+ * With DTLS, mbedtls_ssl_read_record() will:
+ * 1. proceed with the record if this function returns 0
+ * 2. drop only the current record if this function returns UNEXPECTED_RECORD
+ * 3. return CLIENT_RECONNECT if this function return that value
+ * 4. drop the whole datagram if this function returns anything else.
+ * Point 2 is needed when the peer is resending, and we have already received
+ * the first record from a datagram but are still waiting for the others.
+ */
+static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
+ unsigned char *buf,
+ size_t len,
+ mbedtls_record *rec )
+{
+ int major_ver, minor_ver;
+
+ size_t const rec_hdr_type_offset = 0;
+ size_t const rec_hdr_type_len = 1;
+
+ size_t const rec_hdr_version_offset = rec_hdr_type_offset +
+ rec_hdr_type_len;
+ size_t const rec_hdr_version_len = 2;
+
+ size_t const rec_hdr_ctr_len = 8;
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ uint32_t rec_epoch;
+ size_t const rec_hdr_ctr_offset = rec_hdr_version_offset +
+ rec_hdr_version_len;
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ size_t const rec_hdr_cid_offset = rec_hdr_ctr_offset +
+ rec_hdr_ctr_len;
+ size_t rec_hdr_cid_len = 0;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ size_t rec_hdr_len_offset; /* To be determined */
+ size_t const rec_hdr_len_len = 2;
+
+ /*
+ * Check minimum lengths for record header.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ rec_hdr_len_offset = rec_hdr_ctr_offset + rec_hdr_ctr_len;
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ rec_hdr_len_offset = rec_hdr_version_offset + rec_hdr_version_len;
+ }
+
+ if( len < rec_hdr_len_offset + rec_hdr_len_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header of length %u",
+ (unsigned) len,
+ (unsigned)( rec_hdr_len_len + rec_hdr_len_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /*
+ * Parse and validate record content type
+ */
+
+ rec->type = buf[ rec_hdr_type_offset ];
+
+ /* Check record content type */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ rec->cid_len = 0;
+
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->conf->cid_len != 0 &&
+ rec->type == MBEDTLS_SSL_MSG_CID )
+ {
+ /* Shift pointers to account for record header including CID
+ * struct {
+ * ContentType special_type = tls12_cid;
+ * ProtocolVersion version;
+ * uint16 epoch;
+ * uint48 sequence_number;
+ * opaque cid[cid_length]; // Additional field compared to
+ * // default DTLS record format
+ * uint16 length;
+ * opaque enc_content[DTLSCiphertext.length];
+ * } DTLSCiphertext;
+ */
+
+ /* So far, we only support static CID lengths
+ * fixed in the configuration. */
+ rec_hdr_cid_len = ssl->conf->cid_len;
+ rec_hdr_len_offset += rec_hdr_cid_len;
+
+ if( len < rec_hdr_len_offset + rec_hdr_len_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "datagram of length %u too small to hold DTLS record header including CID, length %u",
+ (unsigned) len,
+ (unsigned)( rec_hdr_len_offset + rec_hdr_len_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /* configured CID len is guaranteed at most 255, see
+ * MBEDTLS_SSL_CID_OUT_LEN_MAX in check_config.h */
+ rec->cid_len = (uint8_t) rec_hdr_cid_len;
+ memcpy( rec->cid, buf + rec_hdr_cid_offset, rec_hdr_cid_len );
+ }
+ else
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ {
+ if( ssl_check_record_type( rec->type ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type %u",
+ (unsigned) rec->type ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+ }
+
+ /*
+ * Parse and validate record version
+ */
+
+ rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
+ rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
+ mbedtls_ssl_read_version( &major_ver, &minor_ver,
+ ssl->conf->transport,
+ &rec->ver[0] );
+
+ if( major_ver != ssl->major_ver )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( minor_ver > ssl->conf->max_minor_ver )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /*
+ * Parse/Copy record sequence number.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Copy explicit record sequence number from input buffer. */
+ memcpy( &rec->ctr[0], buf + rec_hdr_ctr_offset,
+ rec_hdr_ctr_len );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ /* Copy implicit record sequence number from SSL context structure. */
+ memcpy( &rec->ctr[0], ssl->in_ctr, rec_hdr_ctr_len );
+ }
+
+ /*
+ * Parse record length.
+ */
+
+ rec->data_offset = rec_hdr_len_offset + rec_hdr_len_len;
+ rec->data_len = ( (size_t) buf[ rec_hdr_len_offset + 0 ] << 8 ) |
+ ( (size_t) buf[ rec_hdr_len_offset + 1 ] << 0 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", buf, rec->data_offset );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %u, "
+ "version = [%d:%d], msglen = %" MBEDTLS_PRINTF_SIZET,
+ rec->type,
+ major_ver, minor_ver, rec->data_len ) );
+
+ rec->buf = buf;
+ rec->buf_len = rec->data_offset + rec->data_len;
+
+ if( rec->data_len == 0 )
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+
+ /*
+ * DTLS-related tests.
+ * Check epoch before checking length constraint because
+ * the latter varies with the epoch. E.g., if a ChangeCipherSpec
+ * message gets duplicated before the corresponding Finished message,
+ * the second ChangeCipherSpec should be discarded because it belongs
+ * to an old epoch, but not because its length is shorter than
+ * the minimum record length for packets using the new record transform.
+ * Note that these two kinds of failures are handled differently,
+ * as an unexpected record is silently skipped but an invalid
+ * record leads to the entire datagram being dropped.
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ rec_epoch = ( rec->ctr[0] << 8 ) | rec->ctr[1];
+
+ /* Check that the datagram is large enough to contain a record
+ * of the advertised length. */
+ if( len < rec->data_offset + rec->data_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Datagram of length %u too small to contain record of advertised length %u.",
+ (unsigned) len,
+ (unsigned)( rec->data_offset + rec->data_len ) ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ /* Records from other, non-matching epochs are silently discarded.
+ * (The case of same-port Client reconnects must be considered in
+ * the caller). */
+ if( rec_epoch != ssl->in_epoch )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
+ "expected %u, received %lu",
+ ssl->in_epoch, (unsigned long) rec_epoch ) );
+
+ /* Records from the next epoch are considered for buffering
+ * (concretely: early Finished messages). */
+ if( rec_epoch == (unsigned) ssl->in_epoch + 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ /* For records from the correct epoch, check whether their
+ * sequence number has been seen before. */
+ else if( mbedtls_ssl_dtls_record_replay_check( (mbedtls_ssl_context *) ssl,
+ &rec->ctr[0] ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+#endif
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ return( 0 );
+}
+
+
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+static int ssl_check_client_reconnect( mbedtls_ssl_context *ssl )
+{
+ unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
+
+ /*
+ * Check for an epoch 0 ClientHello. We can't use in_msg here to
+ * access the first byte of record content (handshake type), as we
+ * have an active transform (possibly iv_len != 0), so use the
+ * fact that the record header len is 13 instead.
+ */
+ if( rec_epoch == 0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_left > 13 &&
+ ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
+ "from the same port" ) );
+ return( ssl_handle_possible_reconnect( ssl ) );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
+
+/*
+ * If applicable, decrypt record content
+ */
+static int ssl_prepare_record_content( mbedtls_ssl_context *ssl,
+ mbedtls_record *rec )
+{
+ int ret, done = 0;
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
+ rec->buf, rec->buf_len );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_read != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
+
+ ret = mbedtls_ssl_hw_record_read( ssl );
+ if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ret == 0 )
+ done = 1;
+ }
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+ if( !done && ssl->transform_in != NULL )
+ {
+ unsigned char const old_msg_type = rec->type;
+
+ if( ( ret = mbedtls_ssl_decrypt_buf( ssl, ssl->transform_in,
+ rec ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID &&
+ ssl->conf->ignore_unexpected_cid
+ == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) );
+ ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ return( ret );
+ }
+
+ if( old_msg_type != rec->type )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d",
+ old_msg_type, rec->type ) );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
+ rec->buf + rec->data_offset, rec->data_len );
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* We have already checked the record content type
+ * in ssl_parse_record_header(), failing or silently
+ * dropping the record in the case of an unknown type.
+ *
+ * Since with the use of CIDs, the record content type
+ * might change during decryption, re-check the record
+ * content type, but treat a failure as fatal this time. */
+ if( ssl_check_record_type( rec->type ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ if( rec->data_len == 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
+ && rec->type != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ ssl->nb_zero++;
+
+ /*
+ * Three or more empty messages may be a DoS attack
+ * (excessive CPU consumption).
+ */
+ if( ssl->nb_zero > 3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
+ "messages, possible DoS attack" ) );
+ /* Treat the records as if they were not properly authenticated,
+ * thereby failing the connection if we see more than allowed
+ * by the configured bad MAC threshold. */
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+ }
+ else
+ ssl->nb_zero = 0;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ; /* in_ctr read from peer, not maintained internally */
+ }
+ else
+#endif
+ {
+ unsigned i;
+ for( i = 8; i > mbedtls_ssl_ep_len( ssl ); i-- )
+ if( ++ssl->in_ctr[i - 1] != 0 )
+ break;
+
+ /* The loop goes to its end iff the counter is wrapping */
+ if( i == mbedtls_ssl_ep_len( ssl ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ mbedtls_ssl_dtls_replay_update( ssl );
+ }
+#endif
+
+ /* Check actual (decrypted) record content length against
+ * configured maximum. */
+ if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Read a record.
+ *
+ * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
+ * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
+ *
+ */
+
+/* Helper functions for mbedtls_ssl_read_record(). */
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
+static int ssl_get_next_record( mbedtls_ssl_context *ssl );
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
+
+int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
+ unsigned update_hs_digest )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
+
+ if( ssl->keep_current_message == 0 )
+ {
+ do {
+
+ ret = ssl_consume_current_message( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ if( ssl_record_is_in_progress( ssl ) == 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ int have_buffered = 0;
+
+ /* We only check for buffered messages if the
+ * current datagram is fully consumed. */
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl_next_record_is_in_datagram( ssl ) == 0 )
+ {
+ if( ssl_load_buffered_message( ssl ) == 0 )
+ have_buffered = 1;
+ }
+
+ if( have_buffered == 0 )
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ret = ssl_get_next_record( ssl );
+ if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
+ continue;
+
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
+ return( ret );
+ }
+ }
+ }
+
+ ret = mbedtls_ssl_handle_message_type( ssl );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ /* Buffer future message */
+ ret = ssl_buffer_message( ssl );
+ if( ret != 0 )
+ return( ret );
+
+ ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
+ MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
+
+ if( 0 != ret )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
+ return( ret );
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ update_hs_digest == 1 )
+ {
+ mbedtls_ssl_update_handshake_status( ssl );
+ }
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
+ ssl->keep_current_message = 0;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_left > ssl->next_record_offset )
+ return( 1 );
+
+ return( 0 );
+}
+
+static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ mbedtls_ssl_hs_buffer * hs_buf;
+ int ret = 0;
+
+ if( hs == NULL )
+ return( -1 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
+
+ if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
+ ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+ {
+ /* Check if we have seen a ChangeCipherSpec before.
+ * If yes, synthesize a CCS record. */
+ if( !hs->buffering.seen_ccs )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
+ ret = -1;
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
+ ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+ ssl->in_msglen = 1;
+ ssl->in_msg[0] = 1;
+
+ /* As long as they are equal, the exact value doesn't matter. */
+ ssl->in_left = 0;
+ ssl->next_record_offset = 0;
+
+ hs->buffering.seen_ccs = 0;
+ goto exit;
+ }
+
+#if defined(MBEDTLS_DEBUG_C)
+ /* Debug only */
+ {
+ unsigned offset;
+ for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+ {
+ hs_buf = &hs->buffering.hs[offset];
+ if( hs_buf->is_valid == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
+ hs->in_msg_seq + offset,
+ hs_buf->is_complete ? "fully" : "partially" ) );
+ }
+ }
+ }
+#endif /* MBEDTLS_DEBUG_C */
+
+ /* Check if we have buffered and/or fully reassembled the
+ * next handshake message. */
+ hs_buf = &hs->buffering.hs[0];
+ if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
+ {
+ /* Synthesize a record containing the buffered HS message. */
+ size_t msg_len = ( hs_buf->data[1] << 16 ) |
+ ( hs_buf->data[2] << 8 ) |
+ hs_buf->data[3];
+
+ /* Double-check that we haven't accidentally buffered
+ * a message that doesn't fit into the input buffer. */
+ if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
+ hs_buf->data, msg_len + 12 );
+
+ ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
+ ssl->in_hslen = msg_len + 12;
+ ssl->in_msglen = msg_len + 12;
+ memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
+
+ ret = 0;
+ goto exit;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
+ hs->in_msg_seq ) );
+ }
+
+ ret = -1;
+
+exit:
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
+ return( ret );
+}
+
+static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
+ size_t desired )
+{
+ int offset;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
+ (unsigned) desired ) );
+
+ /* Get rid of future records epoch first, if such exist. */
+ ssl_free_buffered_record( ssl );
+
+ /* Check if we have enough space available now. */
+ if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
+ return( 0 );
+ }
+
+ /* We don't have enough space to buffer the next expected handshake
+ * message. Remove buffers used for future messages to gain space,
+ * starting with the most distant one. */
+ for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
+ offset >= 0; offset-- )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
+ offset ) );
+
+ ssl_buffering_free_slot( ssl, (uint8_t) offset );
+
+ /* Check if we have enough space available now. */
+ if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
+ return( 0 );
+ }
+ }
+
+ return( -1 );
+}
+
+static int ssl_buffer_message( mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( hs == NULL )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
+
+ switch( ssl->in_msgtype )
+ {
+ case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
+
+ hs->buffering.seen_ccs = 1;
+ break;
+
+ case MBEDTLS_SSL_MSG_HANDSHAKE:
+ {
+ unsigned recv_msg_seq_offset;
+ unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
+ mbedtls_ssl_hs_buffer *hs_buf;
+ size_t msg_len = ssl->in_hslen - 12;
+
+ /* We should never receive an old handshake
+ * message - double-check nonetheless. */
+ if( recv_msg_seq < ssl->handshake->in_msg_seq )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
+ if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+ {
+ /* Silently ignore -- message too far in the future */
+ MBEDTLS_SSL_DEBUG_MSG( 2,
+ ( "Ignore future HS message with sequence number %u, "
+ "buffering window %u - %u",
+ recv_msg_seq, ssl->handshake->in_msg_seq,
+ ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
+
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
+ recv_msg_seq, recv_msg_seq_offset ) );
+
+ hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
+
+ /* Check if the buffering for this seq nr has already commenced. */
+ if( !hs_buf->is_valid )
+ {
+ size_t reassembly_buf_sz;
+
+ hs_buf->is_fragmented =
+ ( ssl_hs_is_proper_fragment( ssl ) == 1 );
+
+ /* We copy the message back into the input buffer
+ * after reassembly, so check that it's not too large.
+ * This is an implementation-specific limitation
+ * and not one from the standard, hence it is not
+ * checked in ssl_check_hs_header(). */
+ if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ /* Ignore message */
+ goto exit;
+ }
+
+ /* Check if we have enough space to buffer the message. */
+ if( hs->buffering.total_bytes_buffered >
+ MBEDTLS_SSL_DTLS_MAX_BUFFERING )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
+ hs_buf->is_fragmented );
+
+ if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ if( recv_msg_seq_offset > 0 )
+ {
+ /* If we can't buffer a future message because
+ * of space limitations -- ignore. */
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- ignore\n",
+ msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ goto exit;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- attempt to make space by freeing buffered future messages\n",
+ msg_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ }
+
+ if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %" MBEDTLS_PRINTF_SIZET
+ " (%" MBEDTLS_PRINTF_SIZET " with bitmap) would exceed"
+ " the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- fail\n",
+ msg_len,
+ reassembly_buf_sz,
+ (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
+ goto exit;
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %" MBEDTLS_PRINTF_SIZET,
+ msg_len ) );
+
+ hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
+ if( hs_buf->data == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
+ hs_buf->data_len = reassembly_buf_sz;
+
+ /* Prepare final header: copy msg_type, length and message_seq,
+ * then add standardised fragment_offset and fragment_length */
+ memcpy( hs_buf->data, ssl->in_msg, 6 );
+ memset( hs_buf->data + 6, 0, 3 );
+ memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
+
+ hs_buf->is_valid = 1;
+
+ hs->buffering.total_bytes_buffered += reassembly_buf_sz;
+ }
+ else
+ {
+ /* Make sure msg_type and length are consistent */
+ if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
+ /* Ignore */
+ goto exit;
+ }
+ }
+
+ if( !hs_buf->is_complete )
+ {
+ size_t frag_len, frag_off;
+ unsigned char * const msg = hs_buf->data + 12;
+
+ /*
+ * Check and copy current fragment
+ */
+
+ /* Validation of header fields already done in
+ * mbedtls_ssl_prepare_handshake_record(). */
+ frag_off = ssl_get_hs_frag_off( ssl );
+ frag_len = ssl_get_hs_frag_len( ssl );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %" MBEDTLS_PRINTF_SIZET
+ ", length = %" MBEDTLS_PRINTF_SIZET,
+ frag_off, frag_len ) );
+ memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
+
+ if( hs_buf->is_fragmented )
+ {
+ unsigned char * const bitmask = msg + msg_len;
+ ssl_bitmask_set( bitmask, frag_off, frag_len );
+ hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
+ msg_len ) == 0 );
+ }
+ else
+ {
+ hs_buf->is_complete = 1;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
+ hs_buf->is_complete ? "" : "not yet " ) );
+ }
+
+ break;
+ }
+
+ default:
+ /* We don't buffer other types of messages. */
+ break;
+ }
+
+exit:
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
+ return( ret );
+}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
+{
+ /*
+ * Consume last content-layer message and potentially
+ * update in_msglen which keeps track of the contents'
+ * consumption state.
+ *
+ * (1) Handshake messages:
+ * Remove last handshake message, move content
+ * and adapt in_msglen.
+ *
+ * (2) Alert messages:
+ * Consume whole record content, in_msglen = 0.
+ *
+ * (3) Change cipher spec:
+ * Consume whole record content, in_msglen = 0.
+ *
+ * (4) Application data:
+ * Don't do anything - the record layer provides
+ * the application data as a stream transport
+ * and consumes through mbedtls_ssl_read only.
+ *
+ */
+
+ /* Case (1): Handshake messages */
+ if( ssl->in_hslen != 0 )
+ {
+ /* Hard assertion to be sure that no application data
+ * is in flight, as corrupting ssl->in_msglen during
+ * ssl->in_offt != NULL is fatal. */
+ if( ssl->in_offt != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Get next Handshake message in the current record
+ */
+
+ /* Notes:
+ * (1) in_hslen is not necessarily the size of the
+ * current handshake content: If DTLS handshake
+ * fragmentation is used, that's the fragment
+ * size instead. Using the total handshake message
+ * size here is faulty and should be changed at
+ * some point.
+ * (2) While it doesn't seem to cause problems, one
+ * has to be very careful not to assume that in_hslen
+ * is always <= in_msglen in a sensible communication.
+ * Again, it's wrong for DTLS handshake fragmentation.
+ * The following check is therefore mandatory, and
+ * should not be treated as a silently corrected assertion.
+ * Additionally, ssl->in_hslen might be arbitrarily out of
+ * bounds after handling a DTLS message with an unexpected
+ * sequence number, see mbedtls_ssl_prepare_handshake_record.
+ */
+ if( ssl->in_hslen < ssl->in_msglen )
+ {
+ ssl->in_msglen -= ssl->in_hslen;
+ memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
+ ssl->in_msglen );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
+ ssl->in_msg, ssl->in_msglen );
+ }
+ else
+ {
+ ssl->in_msglen = 0;
+ }
+
+ ssl->in_hslen = 0;
+ }
+ /* Case (4): Application data */
+ else if( ssl->in_offt != NULL )
+ {
+ return( 0 );
+ }
+ /* Everything else (CCS & Alerts) */
+ else
+ {
+ ssl->in_msglen = 0;
+ }
+
+ return( 0 );
+}
+
+static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
+{
+ if( ssl->in_msglen > 0 )
+ return( 1 );
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ if( hs == NULL )
+ return;
+
+ if( hs->buffering.future_record.data != NULL )
+ {
+ hs->buffering.total_bytes_buffered -=
+ hs->buffering.future_record.len;
+
+ mbedtls_free( hs->buffering.future_record.data );
+ hs->buffering.future_record.data = NULL;
+ }
+}
+
+static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ unsigned char * rec;
+ size_t rec_len;
+ unsigned rec_epoch;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( 0 );
+
+ if( hs == NULL )
+ return( 0 );
+
+ rec = hs->buffering.future_record.data;
+ rec_len = hs->buffering.future_record.len;
+ rec_epoch = hs->buffering.future_record.epoch;
+
+ if( rec == NULL )
+ return( 0 );
+
+ /* Only consider loading future records if the
+ * input buffer is empty. */
+ if( ssl_next_record_is_in_datagram( ssl ) == 1 )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
+
+ if( rec_epoch != ssl->in_epoch )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
+ goto exit;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
+
+ /* Double-check that the record is not too large */
+ if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ memcpy( ssl->in_hdr, rec, rec_len );
+ ssl->in_left = rec_len;
+ ssl->next_record_offset = 0;
+
+ ssl_free_buffered_record( ssl );
+
+exit:
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
+ return( 0 );
+}
+
+static int ssl_buffer_future_record( mbedtls_ssl_context *ssl,
+ mbedtls_record const *rec )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ /* Don't buffer future records outside handshakes. */
+ if( hs == NULL )
+ return( 0 );
+
+ /* Only buffer handshake records (we are only interested
+ * in Finished messages). */
+ if( rec->type != MBEDTLS_SSL_MSG_HANDSHAKE )
+ return( 0 );
+
+ /* Don't buffer more than one future epoch record. */
+ if( hs->buffering.future_record.data != NULL )
+ return( 0 );
+
+ /* Don't buffer record if there's not enough buffering space remaining. */
+ if( rec->buf_len > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
+ hs->buffering.total_bytes_buffered ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %" MBEDTLS_PRINTF_SIZET
+ " would exceed the compile-time limit %" MBEDTLS_PRINTF_SIZET
+ " (already %" MBEDTLS_PRINTF_SIZET
+ " bytes buffered) -- ignore\n",
+ rec->buf_len, (size_t) MBEDTLS_SSL_DTLS_MAX_BUFFERING,
+ hs->buffering.total_bytes_buffered ) );
+ return( 0 );
+ }
+
+ /* Buffer record */
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
+ ssl->in_epoch + 1U ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", rec->buf, rec->buf_len );
+
+ /* ssl_parse_record_header() only considers records
+ * of the next epoch as candidates for buffering. */
+ hs->buffering.future_record.epoch = ssl->in_epoch + 1;
+ hs->buffering.future_record.len = rec->buf_len;
+
+ hs->buffering.future_record.data =
+ mbedtls_calloc( 1, hs->buffering.future_record.len );
+ if( hs->buffering.future_record.data == NULL )
+ {
+ /* If we run out of RAM trying to buffer a
+ * record from the next epoch, just ignore. */
+ return( 0 );
+ }
+
+ memcpy( hs->buffering.future_record.data, rec->buf, rec->buf_len );
+
+ hs->buffering.total_bytes_buffered += rec->buf_len;
+ return( 0 );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+static int ssl_get_next_record( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ mbedtls_record rec;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* We might have buffered a future record; if so,
+ * and if the epoch matches now, load it.
+ * On success, this call will set ssl->in_left to
+ * the length of the buffered record, so that
+ * the calls to ssl_fetch_input() below will
+ * essentially be no-ops. */
+ ret = ssl_load_buffered_record( ssl );
+ if( ret != 0 )
+ return( ret );
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /* Ensure that we have enough space available for the default form
+ * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS,
+ * with no space for CIDs counted in). */
+ ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+ return( ret );
+ }
+
+ ret = ssl_parse_record_header( ssl, ssl->in_hdr, ssl->in_left, &rec );
+ if( ret != 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
+ {
+ ret = ssl_buffer_future_record( ssl, &rec );
+ if( ret != 0 )
+ return( ret );
+
+ /* Fall through to handling of unexpected records */
+ ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
+ }
+
+ if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
+ {
+#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
+ /* Reset in pointers to default state for TLS/DTLS records,
+ * assuming no CID and no offset between record content and
+ * record plaintext. */
+ mbedtls_ssl_update_in_pointers( ssl );
+
+ /* Setup internal message pointers from record structure. */
+ ssl->in_msgtype = rec.type;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_len = ssl->in_cid + rec.cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_msg = ssl->in_len + 2;
+ ssl->in_msglen = rec.data_len;
+
+ ret = ssl_check_client_reconnect( ssl );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_client_reconnect", ret );
+ if( ret != 0 )
+ return( ret );
+#endif
+
+ /* Skip unexpected record (but not whole datagram) */
+ ssl->next_record_offset = rec.buf_len;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
+ "(header)" ) );
+ }
+ else
+ {
+ /* Skip invalid record and the rest of the datagram */
+ ssl->next_record_offset = 0;
+ ssl->in_left = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
+ "(header)" ) );
+ }
+
+ /* Get next record */
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+ else
+#endif
+ {
+ return( ret );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Remember offset of next record within datagram. */
+ ssl->next_record_offset = rec.buf_len;
+ if( ssl->next_record_offset < ssl->in_left )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * Fetch record contents from underlying transport.
+ */
+ ret = mbedtls_ssl_fetch_input( ssl, rec.buf_len );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
+ return( ret );
+ }
+
+ ssl->in_left = 0;
+ }
+
+ /*
+ * Decrypt record contents.
+ */
+
+ if( ( ret = ssl_prepare_record_content( ssl, &rec ) ) != 0 )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Silently discard invalid records */
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ /* Except when waiting for Finished as a bad mac here
+ * probably means something went wrong in the handshake
+ * (eg wrong psk used, mitm downgrade attempt, etc.) */
+ if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
+ ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
+ {
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+ }
+#endif
+ return( ret );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ if( ssl->conf->badmac_limit != 0 &&
+ ++ssl->badmac_seen >= ssl->conf->badmac_limit )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+ }
+#endif
+
+ /* As above, invalid records cause
+ * dismissal of the whole datagram. */
+
+ ssl->next_record_offset = 0;
+ ssl->in_left = 0;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
+ return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
+ }
+
+ return( ret );
+ }
+ else
+#endif
+ {
+ /* Error out (and send alert) on invalid records */
+#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
+ if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
+ {
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
+ }
+#endif
+ return( ret );
+ }
+ }
+
+
+ /* Reset in pointers to default state for TLS/DTLS records,
+ * assuming no CID and no offset between record content and
+ * record plaintext. */
+ mbedtls_ssl_update_in_pointers( ssl );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_len = ssl->in_cid + rec.cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_len + 2;
+
+ /* The record content type may change during decryption,
+ * so re-read it. */
+ ssl->in_msgtype = rec.type;
+ /* Also update the input buffer, because unfortunately
+ * the server-side ssl_parse_client_hello() reparses the
+ * record header when receiving a ClientHello initiating
+ * a renegotiation. */
+ ssl->in_hdr[0] = rec.type;
+ ssl->in_msg = rec.buf + rec.data_offset;
+ ssl->in_msglen = rec.data_len;
+ MBEDTLS_PUT_UINT16_BE( rec.data_len, ssl->in_len, 0 );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->transform_in != NULL &&
+ ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ {
+ if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
+ return( ret );
+ }
+
+ /* Check actual (decompress) record content length against
+ * configured maximum. */
+ if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+ }
+#endif /* MBEDTLS_ZLIB_SUPPORT */
+
+ return( 0 );
+}
+
+int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /*
+ * Handle particular types of records
+ */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ if( ssl->in_msglen != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ if( ssl->in_msg[0] != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
+ ssl->in_msg[0] ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
+ ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
+ {
+ if( ssl->handshake == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
+ return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
+ }
+#endif
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+ {
+ if( ssl->in_msglen != 2 )
+ {
+ /* Note: Standard allows for more than one 2 byte alert
+ to be packed in a single message, but Mbed TLS doesn't
+ currently support this. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %" MBEDTLS_PRINTF_SIZET,
+ ssl->in_msglen ) );
+ return( MBEDTLS_ERR_SSL_INVALID_RECORD );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%u:%u]",
+ ssl->in_msg[0], ssl->in_msg[1] ) );
+
+ /*
+ * Ignore non-fatal alerts, except close_notify and no_renegotiation
+ */
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
+ ssl->in_msg[1] ) );
+ return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
+ }
+
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
+ return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
+ }
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
+ if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
+ /* Will be handled when trying to parse ServerHello */
+ return( 0 );
+ }
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
+ /* Will be handled in mbedtls_ssl_parse_certificate() */
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
+
+ /* Silently ignore: fetch new message */
+ return MBEDTLS_ERR_SSL_NON_FATAL;
+ }
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* Drop unexpected ApplicationData records,
+ * except at the beginning of renegotiations */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
+ ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
+ ssl->state == MBEDTLS_SSL_SERVER_HELLO )
+#endif
+ )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
+ return( MBEDTLS_ERR_SSL_NON_FATAL );
+ }
+
+ if( ssl->handshake != NULL &&
+ ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
+ }
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ return( 0 );
+}
+
+int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
+{
+ return( mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) );
+}
+
+int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
+ unsigned char level,
+ unsigned char message )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
+
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
+ ssl->out_msglen = 2;
+ ssl->out_msg[0] = level;
+ ssl->out_msg[1] = message;
+
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
+
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
+ ssl->out_msglen = 1;
+ ssl->out_msg[0] = 1;
+
+ ssl->state++;
+
+ if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
+
+ return( 0 );
+}
+
+int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
+
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+
+ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+
+ /* CCS records are only accepted if they have length 1 and content '1',
+ * so we don't need to check this here. */
+
+ /*
+ * Switch to our negotiated transform and session parameters for inbound
+ * data.
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
+ ssl->transform_in = ssl->transform_negotiate;
+ ssl->session_in = ssl->session_negotiate;
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ mbedtls_ssl_dtls_replay_reset( ssl );
+#endif
+
+ /* Increment epoch */
+ if( ++ssl->in_epoch == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
+ /* This is highly unlikely to happen for legitimate reasons, so
+ treat it as an attack and don't send an alert. */
+ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ memset( ssl->in_ctr, 0, 8 );
+
+ mbedtls_ssl_update_in_pointers( ssl );
+
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ if( mbedtls_ssl_hw_record_activate != NULL )
+ {
+ if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ }
+#endif
+
+ ssl->state++;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
+
+ return( 0 );
+}
+
+/* Once ssl->out_hdr as the address of the beginning of the
+ * next outgoing record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+static size_t ssl_transform_get_explicit_iv_len(
+ mbedtls_ssl_transform const *transform )
+{
+ if( transform->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
+ return( 0 );
+
+ return( transform->ivlen - transform->fixed_ivlen );
+}
+
+void mbedtls_ssl_update_out_pointers( mbedtls_ssl_context *ssl,
+ mbedtls_ssl_transform *transform )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_ctr = ssl->out_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->out_cid = ssl->out_ctr + 8;
+ ssl->out_len = ssl->out_cid;
+ if( transform != NULL )
+ ssl->out_len += transform->out_cid_len;
+#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_len = ssl->out_ctr + 8;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->out_iv = ssl->out_len + 2;
+ }
+ else
+#endif
+ {
+ ssl->out_ctr = ssl->out_hdr - 8;
+ ssl->out_len = ssl->out_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->out_cid = ssl->out_len;
+#endif
+ ssl->out_iv = ssl->out_hdr + 5;
+ }
+
+ ssl->out_msg = ssl->out_iv;
+ /* Adjust out_msg to make space for explicit IV, if used. */
+ if( transform != NULL )
+ ssl->out_msg += ssl_transform_get_explicit_iv_len( transform );
+}
+
+/* Once ssl->in_hdr as the address of the beginning of the
+ * next incoming record is set, deduce the other pointers.
+ *
+ * Note: For TLS, we save the implicit record sequence number
+ * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
+ * and the caller has to make sure there's space for this.
+ */
+
+void mbedtls_ssl_update_in_pointers( mbedtls_ssl_context *ssl )
+{
+ /* This function sets the pointers to match the case
+ * of unprotected TLS/DTLS records, with both ssl->in_iv
+ * and ssl->in_msg pointing to the beginning of the record
+ * content.
+ *
+ * When decrypting a protected record, ssl->in_msg
+ * will be shifted to point to the beginning of the
+ * record plaintext.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ /* This sets the header pointers to match records
+ * without CID. When we receive a record containing
+ * a CID, the fields are shifted accordingly in
+ * ssl_parse_record_header(). */
+ ssl->in_ctr = ssl->in_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_cid = ssl->in_ctr + 8;
+ ssl->in_len = ssl->in_cid; /* Default: no CID */
+#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_len = ssl->in_ctr + 8;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+ ssl->in_iv = ssl->in_len + 2;
+ }
+ else
+#endif
+ {
+ ssl->in_ctr = ssl->in_hdr - 8;
+ ssl->in_len = ssl->in_hdr + 3;
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl->in_cid = ssl->in_len;
+#endif
+ ssl->in_iv = ssl->in_hdr + 5;
+ }
+
+ /* This will be adjusted at record decryption time. */
+ ssl->in_msg = ssl->in_iv;
+}
+
+/*
+ * Setup an SSL context
+ */
+
+void mbedtls_ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
+{
+ /* Set the incoming and outgoing record pointers. */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ ssl->out_hdr = ssl->out_buf;
+ ssl->in_hdr = ssl->in_buf;
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ {
+ ssl->out_hdr = ssl->out_buf + 8;
+ ssl->in_hdr = ssl->in_buf + 8;
+ }
+
+ /* Derive other internal pointers. */
+ mbedtls_ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
+ mbedtls_ssl_update_in_pointers ( ssl );
+}
+
+/*
+ * SSL get accessors
+ */
+size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
+{
+ return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
+}
+
+int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
+{
+ /*
+ * Case A: We're currently holding back
+ * a message for further processing.
+ */
+
+ if( ssl->keep_current_message == 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
+ return( 1 );
+ }
+
+ /*
+ * Case B: Further records are pending in the current datagram.
+ */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->in_left > ssl->next_record_offset )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
+ return( 1 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+ /*
+ * Case C: A handshake message is being processed.
+ */
+
+ if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
+ return( 1 );
+ }
+
+ /*
+ * Case D: An application data message is being processed
+ */
+ if( ssl->in_offt != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
+ return( 1 );
+ }
+
+ /*
+ * In all other cases, the rest of the message can be dropped.
+ * As in ssl_get_next_record, this needs to be adapted if
+ * we implement support for multiple alerts in single records.
+ */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
+ return( 0 );
+}
+
+
+int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
+{
+ size_t transform_expansion = 0;
+ const mbedtls_ssl_transform *transform = ssl->transform_out;
+ unsigned block_size;
+
+ size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl );
+
+ if( transform == NULL )
+ return( (int) out_hdr_len );
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
+ switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+ {
+ case MBEDTLS_MODE_GCM:
+ case MBEDTLS_MODE_CCM:
+ case MBEDTLS_MODE_CHACHAPOLY:
+ case MBEDTLS_MODE_STREAM:
+ transform_expansion = transform->minlen;
+ break;
+
+ case MBEDTLS_MODE_CBC:
+
+ block_size = mbedtls_cipher_get_block_size(
+ &transform->cipher_ctx_enc );
+
+ /* Expansion due to the addition of the MAC. */
+ transform_expansion += transform->maclen;
+
+ /* Expansion due to the addition of CBC padding;
+ * Theoretically up to 256 bytes, but we never use
+ * more than the block size of the underlying cipher. */
+ transform_expansion += block_size;
+
+ /* For TLS 1.1 or higher, an explicit IV is added
+ * after the record header. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
+ transform_expansion += block_size;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ break;
+
+ default:
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ if( transform->out_cid_len != 0 )
+ transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ return( (int)( out_hdr_len + transform_expansion ) );
+}
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+/*
+ * Check record counters and renegotiate if they're above the limit.
+ */
+static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
+{
+ size_t ep_len = mbedtls_ssl_ep_len( ssl );
+ int in_ctr_cmp;
+ int out_ctr_cmp;
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
+ ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ {
+ return( 0 );
+ }
+
+ in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
+ ssl->conf->renego_period + ep_len, 8 - ep_len );
+ out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
+ ssl->conf->renego_period + ep_len, 8 - ep_len );
+
+ if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
+ {
+ return( 0 );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
+ return( mbedtls_ssl_renegotiate( ssl ) );
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+/*
+ * Receive application data decrypted from the SSL layer
+ */
+int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t n;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ if( ssl->handshake != NULL &&
+ ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
+ {
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ return( ret );
+ }
+ }
+#endif
+
+ /*
+ * Check if renegotiation is necessary and/or handshake is
+ * in process. If yes, perform/continue, and fall through
+ * if an unexpected packet is received while the client
+ * is waiting for the ServerHello.
+ *
+ * (There is no equivalent to the last condition on
+ * the server-side as it is not treated as within
+ * a handshake while waiting for the ClientHello
+ * after a renegotiation request.)
+ */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ ret = ssl_check_ctr_renegotiate( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+ return( ret );
+ }
+#endif
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ ret = mbedtls_ssl_handshake( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+ return( ret );
+ }
+ }
+
+ /* Loop as long as no application data record is available */
+ while( ssl->in_offt == NULL )
+ {
+ /* Start timer if not already running */
+ if( ssl->f_get_timer != NULL &&
+ ssl->f_get_timer( ssl->p_timer ) == -1 )
+ {
+ mbedtls_ssl_set_timer( ssl, ssl->conf->read_timeout );
+ }
+
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+
+ if( ssl->in_msglen == 0 &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ /*
+ * OpenSSL sends empty messages to randomize the IV
+ */
+ if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ {
+ if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
+ return( 0 );
+
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
+ return( ret );
+ }
+ }
+
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
+
+ /*
+ * - For client-side, expect SERVER_HELLO_REQUEST.
+ * - For server-side, expect CLIENT_HELLO.
+ * - Fail (TLS) or silently drop record (DTLS) in other cases.
+ */
+
+#if defined(MBEDTLS_SSL_CLI_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
+ ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
+
+ /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ continue;
+ }
+#endif
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+#endif /* MBEDTLS_SSL_CLI_C */
+
+#if defined(MBEDTLS_SSL_SRV_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
+
+ /* With DTLS, drop the packet (probably from last handshake) */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ continue;
+ }
+#endif
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ /* Determine whether renegotiation attempt should be accepted */
+ if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
+ ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
+ ssl->conf->allow_legacy_renegotiation ==
+ MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
+ {
+ /*
+ * Accept renegotiation request
+ */
+
+ /* DTLS clients need to know renego is server-initiated */
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ {
+ ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
+ }
+#endif
+ ret = mbedtls_ssl_start_renegotiation( ssl );
+ if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
+ ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation",
+ ret );
+ return( ret );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+ {
+ /*
+ * Refuse renegotiation
+ */
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ /* SSLv3 does not have a "no_renegotiation" warning, so
+ we send a fatal alert and abort the connection. */
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ {
+ if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+ MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+ else
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
+ MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ }
+
+ /* At this point, we don't know whether the renegotiation has been
+ * completed or not. The cases to consider are the following:
+ * 1) The renegotiation is complete. In this case, no new record
+ * has been read yet.
+ * 2) The renegotiation is incomplete because the client received
+ * an application data record while awaiting the ServerHello.
+ * 3) The renegotiation is incomplete because the client received
+ * a non-handshake, non-application data message while awaiting
+ * the ServerHello.
+ * In each of these case, looping will be the proper action:
+ * - For 1), the next iteration will read a new record and check
+ * if it's application data.
+ * - For 2), the loop condition isn't satisfied as application data
+ * is present, hence continue is the same as break
+ * - For 3), the loop condition is satisfied and read_record
+ * will re-deliver the message that was held back by the client
+ * when expecting the ServerHello.
+ */
+ continue;
+ }
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ssl->conf->renego_max_records >= 0 )
+ {
+ if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
+ "but not honored by client" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+ }
+ }
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
+
+ /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
+ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
+ return( MBEDTLS_ERR_SSL_WANT_READ );
+ }
+
+ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
+ return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
+ }
+
+ ssl->in_offt = ssl->in_msg;
+
+ /* We're going to return something now, cancel timer,
+ * except if handshake (renegotiation) is in progress */
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ mbedtls_ssl_set_timer( ssl, 0 );
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ /* If we requested renego but received AppData, resend HelloRequest.
+ * Do it now, after setting in_offt, to avoid taking this branch
+ * again if ssl_write_hello_request() returns WANT_WRITE */
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
+ {
+ if( ( ret = mbedtls_ssl_resend_hello_request( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend_hello_request",
+ ret );
+ return( ret );
+ }
+ }
+#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ }
+
+ n = ( len < ssl->in_msglen )
+ ? len : ssl->in_msglen;
+
+ 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 */
+ ssl->in_offt = NULL;
+ ssl->keep_current_message = 0;
+ }
+ else
+ {
+ /* more data available */
+ ssl->in_offt += n;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
+
+ return( (int) n );
+}
+
+/*
+ * Send application data to be encrypted by the SSL layer, taking care of max
+ * fragment length and buffer size.
+ *
+ * According to RFC 5246 Section 6.2.1:
+ *
+ * Zero-length fragments of Application data MAY be sent as they are
+ * potentially useful as a traffic analysis countermeasure.
+ *
+ * Therefore, it is possible that the input message length is 0 and the
+ * corresponding return code is 0 on success.
+ */
+static int ssl_write_real( mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len )
+{
+ int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
+ const size_t max_len = (size_t) ret;
+
+ if( ret < 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
+ return( ret );
+ }
+
+ if( len > max_len )
+ {
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
+ "maximum fragment length: %" MBEDTLS_PRINTF_SIZET
+ " > %" MBEDTLS_PRINTF_SIZET,
+ len, max_len ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ else
+#endif
+ len = max_len;
+ }
+
+ if( ssl->out_left != 0 )
+ {
+ /*
+ * The user has previously tried to send the data and
+ * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
+ * written. In this case, we expect the high-level write function
+ * (e.g. mbedtls_ssl_write()) to be called with the same parameters
+ */
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
+ return( ret );
+ }
+ }
+ else
+ {
+ /*
+ * The user is trying to send a message the first time, so we need to
+ * copy the data into the internal buffers and setup the data structure
+ * to keep track of partial writes
+ */
+ ssl->out_msglen = len;
+ ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
+ memcpy( ssl->out_msg, buf, len );
+
+ if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ }
+
+ return( (int) len );
+}
+
+/*
+ * Write application data, doing 1/n-1 splitting if necessary.
+ *
+ * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
+ * then the caller will call us again with the same arguments, so
+ * remember whether we already did the split or not.
+ */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+static int ssl_write_split( mbedtls_ssl_context *ssl,
+ const unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl->conf->cbc_record_splitting ==
+ MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
+ len <= 1 ||
+ ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
+ mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
+ != MBEDTLS_MODE_CBC )
+ {
+ return( ssl_write_real( ssl, buf, len ) );
+ }
+
+ if( ssl->split_done == 0 )
+ {
+ if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
+ return( ret );
+ ssl->split_done = 1;
+ }
+
+ if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
+ return( ret );
+ ssl->split_done = 0;
+
+ return( ret + 1 );
+}
+#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
+
+/*
+ * Write application data (public-facing wrapper)
+ */
+int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
+ return( ret );
+ }
+#endif
+
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
+ return( ret );
+ }
+ }
+
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ ret = ssl_write_split( ssl, buf, len );
+#else
+ ret = ssl_write_real( ssl, buf, len );
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
+
+ return( ret );
+}
+
+/*
+ * Notify the peer that the connection is being closed
+ */
+int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( ssl == NULL || ssl->conf == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
+
+ if( ssl->out_left != 0 )
+ return( mbedtls_ssl_flush_output( ssl ) );
+
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ if( ( ret = mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_WARNING,
+ MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
+ return( ret );
+ }
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
+
+ return( 0 );
+}
+
+void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
+{
+ if( transform == NULL )
+ return;
+
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ deflateEnd( &transform->ctx_deflate );
+ inflateEnd( &transform->ctx_inflate );
+#endif
+
+ mbedtls_cipher_free( &transform->cipher_ctx_enc );
+ mbedtls_cipher_free( &transform->cipher_ctx_dec );
+
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ mbedtls_md_free( &transform->md_ctx_enc );
+ mbedtls_md_free( &transform->md_ctx_dec );
+#endif
+
+ mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
+}
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+
+void mbedtls_ssl_buffering_free( mbedtls_ssl_context *ssl )
+{
+ unsigned offset;
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+
+ if( hs == NULL )
+ return;
+
+ ssl_free_buffered_record( ssl );
+
+ for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
+ ssl_buffering_free_slot( ssl, offset );
+}
+
+static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
+ uint8_t slot )
+{
+ mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
+
+ if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
+ return;
+
+ if( hs_buf->is_valid == 1 )
+ {
+ hs->buffering.total_bytes_buffered -= hs_buf->data_len;
+ mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
+ mbedtls_free( hs_buf->data );
+ memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
+ }
+}
+
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+/*
+ * Convert version numbers to/from wire format
+ * and, for DTLS, to/from TLS equivalent.
+ *
+ * For TLS this is the identity.
+ * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
+ * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
+ * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
+ */
+void mbedtls_ssl_write_version( int major, int minor, int transport,
+ unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
+ --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+
+ ver[0] = (unsigned char)( 255 - ( major - 2 ) );
+ ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
+ }
+ else
+#else
+ ((void) transport);
+#endif
+ {
+ ver[0] = (unsigned char) major;
+ ver[1] = (unsigned char) minor;
+ }
+}
+
+void mbedtls_ssl_read_version( int *major, int *minor, int transport,
+ const unsigned char ver[2] )
+{
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ *major = 255 - ver[0] + 2;
+ *minor = 255 - ver[1] + 1;
+
+ if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
+ ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
+ }
+ else
+#else
+ ((void) transport);
+#endif
+ {
+ *major = ver[0];
+ *minor = ver[1];
+ }
+}
+
+#endif /* MBEDTLS_SSL_TLS_C */
diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c
index cbf6142ac2..1a63173204 100644
--- a/thirdparty/mbedtls/library/ssl_srv.c
+++ b/thirdparty/mbedtls/library/ssl_srv.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 server-side functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_SRV_C)
@@ -60,10 +29,13 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "constant_time_internal.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
@@ -110,7 +82,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t servername_list_size, hostname_len;
const unsigned char *p;
@@ -174,6 +146,48 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+static int ssl_conf_has_psk_or_cb( mbedtls_ssl_config const *conf )
+{
+ if( conf->f_psk != NULL )
+ return( 1 );
+
+ if( conf->psk_identity_len == 0 || conf->psk_identity == NULL )
+ return( 0 );
+
+ if( conf->psk != NULL && conf->psk_len != 0 )
+ return( 1 );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
+ return( 1 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
+ return( 0 );
+}
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
+{
+ if( ssl->conf->f_psk != NULL )
+ {
+ /* If we've used a callback to select the PSK,
+ * the static configuration is irrelevant. */
+
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+ }
+
+ if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
+
static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
@@ -184,7 +198,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
/* Check verify-data in constant-time. The length OTOH is no secret */
if( len != 1 + ssl->verify_data_len ||
buf[0] != ssl->verify_data_len ||
- mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data,
+ mbedtls_ct_memcmp( buf + 1, ssl->peer_verify_data,
ssl->verify_data_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) );
@@ -211,7 +225,7 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl,
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Status of the implementation of signature-algorithms extension:
@@ -286,20 +300,20 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl,
{
mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:"
- " match sig %d and hash %d",
- sig_cur, md_cur ) );
+ " match sig %u and hash %u",
+ (unsigned) sig_cur, (unsigned) md_cur ) );
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: "
- "hash alg %d not supported", md_cur ) );
+ "hash alg %u not supported", (unsigned) md_cur ) );
}
}
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -415,7 +429,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
{
@@ -458,6 +472,78 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ size_t peer_cid_len;
+
+ /* CID extension only makes sense in DTLS */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+
+ if( len < 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ peer_cid_len = *buf++;
+ len--;
+
+ if( len != peer_cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /* Ignore CID if the user has disabled its use. */
+ if( ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
+ {
+ /* Leave ssl->handshake->cid_in_use in its default
+ * value of MBEDTLS_SSL_CID_DISABLED. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Client sent CID extension, but CID disabled" ) );
+ return( 0 );
+ }
+
+ if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED;
+ ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len;
+ memcpy( ssl->handshake->peer_cid, buf, peer_cid_len );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Client CID", buf, peer_cid_len );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf,
@@ -535,7 +621,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_session session;
mbedtls_ssl_session_init( &session );
@@ -549,7 +635,7 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
/* Remember the client asked us to send a new ticket */
ssl->handshake->new_session_ticket = 1;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %" MBEDTLS_PRINTF_SIZET, len ) );
if( len == 0 )
return( 0 );
@@ -692,6 +778,126 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+static int ssl_parse_use_srtp_ext( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
+{
+ mbedtls_ssl_srtp_profile client_protection = MBEDTLS_TLS_SRTP_UNSET;
+ size_t i,j;
+ size_t profile_length;
+ uint16_t mki_length;
+ /*! 2 bytes for profile length and 1 byte for mki len */
+ const size_t size_of_lengths = 3;
+
+ /* If use_srtp is not configured, just ignore the extension */
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->conf->dtls_srtp_profile_list == NULL ) ||
+ ( ssl->conf->dtls_srtp_profile_list_len == 0 ) )
+ {
+ return( 0 );
+ }
+
+ /* RFC5764 section 4.1.1
+ * uint8 SRTPProtectionProfile[2];
+ *
+ * struct {
+ * SRTPProtectionProfiles SRTPProtectionProfiles;
+ * opaque srtp_mki<0..255>;
+ * } UseSRTPData;
+
+ * SRTPProtectionProfile SRTPProtectionProfiles<2..2^16-1>;
+ */
+
+ /*
+ * Min length is 5: at least one protection profile(2 bytes)
+ * and length(2 bytes) + srtp_mki length(1 byte)
+ * Check here that we have at least 2 bytes of protection profiles length
+ * and one of srtp_mki length
+ */
+ if( len < size_of_lengths )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = MBEDTLS_TLS_SRTP_UNSET;
+
+ /* first 2 bytes are protection profile length(in bytes) */
+ profile_length = ( buf[0] << 8 ) | buf[1];
+ buf += 2;
+
+ /* The profile length cannot be bigger than input buffer size - lengths fields */
+ if( profile_length > len - size_of_lengths ||
+ profile_length % 2 != 0 ) /* profiles are 2 bytes long, so the length must be even */
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+ /*
+ * parse the extension list values are defined in
+ * http://www.iana.org/assignments/srtp-protection/srtp-protection.xhtml
+ */
+ for( j = 0; j < profile_length; j += 2 )
+ {
+ uint16_t protection_profile_value = buf[j] << 8 | buf[j + 1];
+ client_protection = mbedtls_ssl_check_srtp_profile_value( protection_profile_value );
+
+ if( client_protection != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ client_protection ) ) );
+ }
+ else
+ {
+ continue;
+ }
+ /* check if suggested profile is in our list */
+ for( i = 0; i < ssl->conf->dtls_srtp_profile_list_len; i++)
+ {
+ if( client_protection == ssl->conf->dtls_srtp_profile_list[i] )
+ {
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile = ssl->conf->dtls_srtp_profile_list[i];
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "selected srtp profile: %s",
+ mbedtls_ssl_get_srtp_profile_as_string(
+ client_protection ) ) );
+ break;
+ }
+ }
+ if( ssl->dtls_srtp_info.chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_UNSET )
+ break;
+ }
+ buf += profile_length; /* buf points to the mki length */
+ mki_length = *buf;
+ buf++;
+
+ if( mki_length > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH ||
+ mki_length + profile_length + size_of_lengths != len )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
+ }
+
+ /* Parse the mki only if present and mki is supported locally */
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED &&
+ mki_length > 0 )
+ {
+ ssl->dtls_srtp_info.mki_len = mki_length;
+
+ memcpy( ssl->dtls_srtp_info.mki_value, buf, mki_length );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "using mki", ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+
+ return( 0 );
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
/*
* Auxiliary functions for ServerHello parsing and related actions
*/
@@ -750,6 +956,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
for( cur = list; cur != NULL; cur = cur->next )
{
+ flags = 0;
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
cur->cert );
@@ -831,7 +1038,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
const mbedtls_ssl_ciphersuite_t *suite_info;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
mbedtls_pk_type_t sig_type;
#endif
@@ -842,7 +1049,8 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %#04x (%s)",
+ (unsigned int) suite_id, suite_info->name ) );
if( suite_info->min_minor_ver > ssl->minor_ver ||
suite_info->max_minor_ver < ssl->minor_ver )
@@ -888,13 +1096,11 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
}
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
/* If the ciphersuite requires a pre-shared key and we don't
* have one, skip it now rather than failing later */
if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) &&
- ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+ ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) );
return( 0 );
@@ -902,7 +1108,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* If the ciphersuite requires signing, check whether
* a suitable hash algorithm is present. */
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
@@ -912,13 +1118,13 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm "
- "for signature algorithm %d", sig_type ) );
+ "for signature algorithm %u", (unsigned) sig_type ) );
return( 0 );
}
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/*
@@ -1043,7 +1249,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
sess_len = ( buf[2] << 8 ) | buf[3];
chal_len = ( buf[4] << 8 ) | buf[5];
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %u, sess_len: %u, chal_len: %u",
ciph_len, sess_len, chal_len ) );
/*
@@ -1118,8 +1324,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 )
{
if( p[0] == 0 &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
+ MBEDTLS_GET_UINT16_BE(p, 1) != MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) );
@@ -1150,8 +1355,7 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl )
#endif
{
if( p[0] != 0 ||
- p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[2] != ( ( ciphersuites[i] ) & 0xFF ) )
+ MBEDTLS_GET_UINT16_BE(p, 1) != ciphersuites[i] )
continue;
got_common_suite = 1;
@@ -1180,7 +1384,7 @@ have_ciphersuite_v2:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+ ssl->handshake->ciphersuite_info = ciphersuite_info;
/*
* SSLv2 Client Hello relevant renegotiation security checks
@@ -1228,10 +1432,10 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl )
* we need to fall back to the default values for allowed
* signature-hash pairs. */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
int sig_hash_alg_ext_present = 0;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
@@ -1265,7 +1469,7 @@ read_record_header:
return( ssl_parse_client_hello_v2( ssl ) );
#endif
- MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) );
/*
* SSLv3/TLS Client Hello
@@ -1354,7 +1558,7 @@ read_record_header:
}
if( ( ret = mbedtls_ssl_fetch_input( ssl,
- mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 )
+ mbedtls_ssl_in_hdr_len( ssl ) + msg_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
return( ret );
@@ -1363,7 +1567,7 @@ read_record_header:
/* Done reading this record, get ready for the next one */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl );
+ ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl );
else
#endif
ssl->in_left = 0;
@@ -1425,7 +1629,7 @@ read_record_header:
if( cli_msg_seq != ssl->handshake->in_msg_seq )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: "
- "%d (expected %d)", cli_msg_seq,
+ "%u (expected %u)", cli_msg_seq,
ssl->handshake->in_msg_seq ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
@@ -1683,8 +1887,7 @@ read_record_header:
ext_len = ( buf[ext_offset + 0] << 8 )
| ( buf[ext_offset + 1] );
- if( ( ext_len > 0 && ext_len < 4 ) ||
- msg_len != ext_offset + 2 + ext_len )
+ if( msg_len != ext_offset + 2 + ext_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -1744,7 +1947,7 @@ read_record_header:
break;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
@@ -1755,7 +1958,7 @@ read_record_header:
sig_hash_alg_ext_present = 1;
break;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
@@ -1808,6 +2011,16 @@ read_record_header:
break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ case MBEDTLS_TLS_EXT_CID:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) );
+
+ ret = ssl_parse_cid_ext( ssl, ext + 4, ext_size );
+ if( ret != 0 )
+ return( ret );
+ break;
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
@@ -1848,21 +2061,23 @@ read_record_header:
break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ case MBEDTLS_TLS_EXT_USE_SRTP:
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "found use_srtp extension" ) );
+
+ ret = ssl_parse_use_srtp_ext( ssl, ext + 4, ext_size );
+ if( ret != 0 )
+ return( ret );
+ break;
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
default:
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %u (ignoring)",
ext_id ) );
}
ext_len -= 4 + ext_size;
ext += 4 + ext_size;
-
- if( ext_len > 0 && ext_len < 4 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
}
@@ -1871,8 +2086,7 @@ read_record_header:
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 )
{
- if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) &&
- p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) )
+ if( MBEDTLS_GET_UINT16_BE( p, 0 ) == MBEDTLS_SSL_FALLBACK_SCSV_VALUE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) );
@@ -1892,7 +2106,7 @@ read_record_header:
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Try to fall back to default hash SHA1 if the client
@@ -1909,7 +2123,7 @@ read_record_header:
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/*
* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV
@@ -1990,8 +2204,7 @@ read_record_header:
for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 )
#endif
{
- if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) ||
- p[1] != ( ( ciphersuites[i] ) & 0xFF ) )
+ if( MBEDTLS_GET_UINT16_BE(p, 0) != ciphersuites[i] )
continue;
got_common_suite = 1;
@@ -2024,7 +2237,7 @@ have_ciphersuite:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
- ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
+ ssl->handshake->ciphersuite_info = ciphersuite_info;
ssl->state++;
@@ -2036,7 +2249,7 @@ have_ciphersuite:
/* Debugging-only output for testsuite */
#if defined(MBEDTLS_DEBUG_C) && \
defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info );
@@ -2050,7 +2263,7 @@ have_ciphersuite:
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm "
- "%d - should not happen", sig_alg ) );
+ "%u - should not happen", (unsigned) sig_alg ) );
}
}
#endif
@@ -2075,8 +2288,8 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_TRUNCATED_HMAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2085,6 +2298,53 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+static void ssl_write_cid_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t ext_len;
+ const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+ *olen = 0;
+
+ /* Skip writing the extension if we don't want to use it or if
+ * the client hasn't offered it. */
+ if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED )
+ return;
+
+ /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX
+ * which is at most 255, so the increment cannot overflow. */
+ if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) );
+
+ /*
+ * Quoting draft-ietf-tls-dtls-connection-id-05
+ * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05
+ *
+ * struct {
+ * opaque cid<0..2^8-1>;
+ * } ConnectionId;
+ */
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_CID, p, 0 );
+ p += 2;
+ ext_len = (size_t) ssl->own_cid_len + 1;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2;
+
+ *p++ = (uint8_t) ssl->own_cid_len;
+ memcpy( p, ssl->own_cid, ssl->own_cid_len );
+
+ *olen = ssl->own_cid_len + 5;
+}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
@@ -2118,8 +2378,8 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2145,8 +2405,8 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret "
"extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2170,8 +2430,8 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SESSION_TICKET, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 0x00;
@@ -2194,8 +2454,8 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO, p, 0 );
+ p += 2;
#if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
@@ -2235,8 +2495,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 1;
@@ -2265,8 +2525,8 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS, p, 0 );
+ p += 2;
*p++ = 0x00;
*p++ = 2;
@@ -2283,7 +2543,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
size_t kkpp_len;
@@ -2291,7 +2551,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
*olen = 0;
/* Skip costly computation if not needed */
- if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
+ if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
@@ -2303,8 +2563,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
return;
}
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ECJPAKE_KKPP, p, 0 );
+ p += 2;
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
@@ -2315,8 +2575,8 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
return;
}
- *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( kkpp_len, p, 0 );
+ p += 2;
*olen = kkpp_len + 4;
}
@@ -2341,27 +2601,93 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
* 6 . 6 protocol name length
* 7 . 7+n protocol name
*/
- buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
- buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( MBEDTLS_TLS_EXT_ALPN, buf, 0);
*olen = 7 + strlen( ssl->alpn_chosen );
- buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF );
- buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 4, buf, 2 );
- buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF );
- buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF );
+ MBEDTLS_PUT_UINT16_BE( *olen - 6, buf, 4 );
- buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF );
+ buf[6] = MBEDTLS_BYTE_0( *olen - 7 );
memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 );
}
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */
+#if defined(MBEDTLS_SSL_DTLS_SRTP ) && defined(MBEDTLS_SSL_PROTO_DTLS)
+static void ssl_write_use_srtp_ext( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t *olen )
+{
+ size_t mki_len = 0, ext_len = 0;
+ uint16_t profile_value = 0;
+ const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
+
+ *olen = 0;
+
+ if( ( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) ||
+ ( ssl->dtls_srtp_info.chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET ) )
+ {
+ return;
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding use_srtp extension" ) );
+
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_SUPPORTED )
+ {
+ mki_len = ssl->dtls_srtp_info.mki_len;
+ }
+
+ /* The extension total size is 9 bytes :
+ * - 2 bytes for the extension tag
+ * - 2 bytes for the total size
+ * - 2 bytes for the protection profile length
+ * - 2 bytes for the protection profile
+ * - 1 byte for the mki length
+ * + the actual mki length
+ * Check we have enough room in the output buffer */
+ if( (size_t)( end - buf ) < mki_len + 9 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
+ return;
+ }
+
+ /* extension */
+ MBEDTLS_PUT_UINT16_BE(MBEDTLS_TLS_EXT_USE_SRTP, buf, 0 );
+ /*
+ * total length 5 and mki value: only one profile(2 bytes)
+ * and length(2 bytes) and srtp_mki )
+ */
+ ext_len = 5 + mki_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, buf, 2 );
+
+ /* protection profile length: 2 */
+ buf[4] = 0x00;
+ buf[5] = 0x02;
+ profile_value = mbedtls_ssl_check_srtp_profile_value(
+ ssl->dtls_srtp_info.chosen_dtls_srtp_profile );
+ if( profile_value != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ MBEDTLS_PUT_UINT16_BE( profile_value, buf, 6 );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "use_srtp extension invalid profile" ) );
+ return;
+ }
+
+ buf[8] = mki_len & 0xFF;
+ memcpy( &buf[9], ssl->dtls_srtp_info.mki_value, mki_len );
+
+ *olen = 9 + mki_len;
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p = ssl->out_msg + 4;
unsigned char *cookie_len_byte;
@@ -2430,12 +2756,61 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+static void ssl_handle_id_based_session_resumption( mbedtls_ssl_context *ssl )
+{
+ int ret;
+ mbedtls_ssl_session session_tmp;
+ mbedtls_ssl_session * const session = ssl->session_negotiate;
+
+ /* Resume is 0 by default, see ssl_handshake_init().
+ * It may be already set to 1 by ssl_parse_session_ticket_ext(). */
+ if( ssl->handshake->resume == 1 )
+ return;
+ if( session->id_len == 0 )
+ return;
+ if( ssl->conf->f_get_cache == NULL )
+ return;
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE )
+ return;
+#endif
+
+ mbedtls_ssl_session_init( &session_tmp );
+
+ session_tmp.id_len = session->id_len;
+ memcpy( session_tmp.id, session->id, session->id_len );
+
+ ret = ssl->conf->f_get_cache( ssl->conf->p_cache,
+ &session_tmp );
+ if( ret != 0 )
+ goto exit;
+
+ if( session->ciphersuite != session_tmp.ciphersuite ||
+ session->compression != session_tmp.compression )
+ {
+ /* Mismatch between cached and negotiated session */
+ goto exit;
+ }
+
+ /* Move semantics */
+ mbedtls_ssl_session_free( session );
+ *session = session_tmp;
+ memset( &session_tmp, 0, sizeof( session_tmp ) );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
+ ssl->handshake->resume = 1;
+
+exit:
+
+ mbedtls_ssl_session_free( &session_tmp );
+}
+
static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t t;
#endif
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen, ext_len = 0, n;
unsigned char *buf, *p;
@@ -2477,12 +2852,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_HAVE_TIME)
t = mbedtls_time( NULL );
- *p++ = (unsigned char)( t >> 24 );
- *p++ = (unsigned char)( t >> 16 );
- *p++ = (unsigned char)( t >> 8 );
- *p++ = (unsigned char)( t );
+ MBEDTLS_PUT_UINT32_BE( t, p, 0 );
+ p += 4;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %" MBEDTLS_PRINTF_LONGLONG,
+ (long long) t ) );
#else
if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 )
return( ret );
@@ -2499,22 +2873,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 );
- /*
- * Resume is 0 by default, see ssl_handshake_init().
- * It may be already set to 1 by ssl_parse_session_ticket_ext().
- * If not, try looking up session ID in our cache.
- */
- if( ssl->handshake->resume == 0 &&
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE &&
-#endif
- ssl->session_negotiate->id_len != 0 &&
- ssl->conf->f_get_cache != NULL &&
- ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) );
- ssl->handshake->resume = 1;
- }
+ ssl_handle_id_based_session_resumption( ssl );
if( ssl->handshake->resume == 0 )
{
@@ -2570,19 +2929,19 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len );
p += ssl->session_negotiate->id_len;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %" MBEDTLS_PRINTF_SIZET, n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 );
- *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite );
- *p++ = (unsigned char)( ssl->session_negotiate->compression );
+ MBEDTLS_PUT_UINT16_BE( ssl->session_negotiate->ciphersuite, p, 0 );
+ p += 2;
+ *p++ = MBEDTLS_BYTE_0( ssl->session_negotiate->compression );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s",
mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
- ssl->session_negotiate->compression ) );
+ (unsigned int) ssl->session_negotiate->compression ) );
/* Do not write the extensions if the protocol is SSLv3 */
#if defined(MBEDTLS_SSL_PROTO_SSL3)
@@ -2606,6 +2965,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+#endif
+
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
@@ -2641,13 +3005,18 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen;
#endif
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) );
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ ssl_write_use_srtp_ext( ssl, p + 2 + ext_len, &olen );
+ ext_len += olen;
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %" MBEDTLS_PRINTF_SIZET,
+ ext_len ) );
if( ext_len > 0 )
{
- *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( ext_len ) & 0xFF );
- p += ext_len;
+ MBEDTLS_PUT_UINT16_BE( ext_len, p, 0 );
+ p += 2 + ext_len;
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
@@ -2665,24 +3034,15 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
return( ret );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
ssl->state++;
@@ -2692,13 +3052,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
- size_t dn_size, total_dn_size; /* excluding length bytes */
+ ssl->handshake->ciphersuite_info;
+ uint16_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p;
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN;
@@ -2716,11 +3076,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#endif
authmode = ssl->conf->authmode;
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
authmode == MBEDTLS_SSL_VERIFY_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@@ -2799,8 +3155,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#endif
}
- p[0] = (unsigned char)( sa_len >> 8 );
- p[1] = (unsigned char)( sa_len );
+ MBEDTLS_PUT_UINT16_BE( sa_len, p, 0 );
sa_len += 2;
p += sa_len;
}
@@ -2816,6 +3171,11 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED )
{
+ /* NOTE: If trusted certificates are provisioned
+ * via a CA callback (configured through
+ * `mbedtls_ssl_conf_ca_cb()`, then the
+ * CertificateRequest is currently left empty. */
+
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
if( ssl->handshake->sni_ca_chain != NULL )
crt = ssl->handshake->sni_ca_chain;
@@ -2825,18 +3185,18 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
while( crt != NULL && crt->version != 0 )
{
- dn_size = crt->subject_raw.len;
+ /* It follows from RFC 5280 A.1 that this length
+ * can be represented in at most 11 bits. */
+ dn_size = (uint16_t) crt->subject_raw.len;
- if( end < p ||
- (size_t)( end - p ) < dn_size ||
- (size_t)( end - p ) < 2 + dn_size )
+ if( end < p || (size_t)( end - p ) < 2 + (size_t) dn_size )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) );
break;
}
- *p++ = (unsigned char)( dn_size >> 8 );
- *p++ = (unsigned char)( dn_size );
+ MBEDTLS_PUT_UINT16_BE( dn_size, p, 0 );
+ p += 2;
memcpy( p, crt->subject_raw.p, dn_size );
p += dn_size;
@@ -2850,8 +3210,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
ssl->out_msglen = p - buf;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST;
- ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
- ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
+ MBEDTLS_PUT_UINT16_BE( total_dn_size, ssl->out_msg, 4 + ct_len + sa_len );
ret = mbedtls_ssl_write_handshake_msg( ssl );
@@ -2859,18 +3218,13 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) )
{
@@ -2891,7 +3245,7 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
@@ -2914,7 +3268,7 @@ static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
return( ret );
}
-#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
/* Prepare the ServerKeyExchange message, up to and including
@@ -2924,17 +3278,18 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+ ssl->handshake->ciphersuite_info;
+
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
unsigned char *dig_signed = NULL;
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PFS_ENABLED */
(void) ciphersuite_info; /* unused in some configurations */
-#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
(void) signature_len;
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
@@ -2950,7 +3305,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
ret = mbedtls_ecjpake_write_round_two(
@@ -2987,10 +3342,10 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
/*
* - DHE key exchanges
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
@@ -3026,7 +3381,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
return( ret );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
@@ -3037,12 +3392,12 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_DHE_ENABLED */
/*
* - ECDHE key exchanges
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) )
{
/*
@@ -3055,7 +3410,7 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
*/
const mbedtls_ecp_curve_info **curve = NULL;
const mbedtls_ecp_group_id *gid;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/* Match our preference list against the offered curves */
@@ -3090,7 +3445,7 @@ curve_matching_done:
return( ret );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
dig_signed = ssl->out_msg + ssl->out_msglen;
#endif
@@ -3099,7 +3454,7 @@ curve_matching_done:
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Q );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDHE_ENABLED */
/*
*
@@ -3107,13 +3462,17 @@ curve_matching_done:
* exchange parameters, compute and add the signature here.
*
*/
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
{
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
size_t hashlen = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ unsigned char hash[PSA_HASH_MAX_SIZE];
+#else
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
- int ret;
+#endif
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/*
* 2.1: Choose hash algorithm:
@@ -3160,7 +3519,7 @@ curve_matching_done:
md_alg = MBEDTLS_MD_NONE;
}
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %u for signing", (unsigned) md_alg ) );
/*
* 2.2: Compute the hash to be signed
@@ -3275,7 +3634,7 @@ curve_matching_done:
return( ret );
}
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
return( 0 );
}
@@ -3286,28 +3645,28 @@ curve_matching_done:
* machine. */
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t signature_len = 0;
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+ ssl->handshake->ciphersuite_info;
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED)
/* Extract static ECDH parameters and abort if ServerKeyExchange
* is not needed. */
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
{
/* For suites involving ECDH, extract DH parameters
* from certificate at this point. */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED)
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
{
ssl_get_ecdh_params_from_cert( ssl );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_ECDH_ENABLED */
/* Key exchanges not involving ephemeral keys don't use
* ServerKeyExchange, so end here. */
@@ -3315,9 +3674,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
ssl->state++;
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_NON_PFS_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) && \
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/* If we have already prepared the message and there is an ongoing
* signature operation, resume signing. */
@@ -3327,7 +3686,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
ret = ssl_resume_server_key_exchange( ssl, &signature_len );
}
else
-#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
+#endif /* defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED) &&
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
{
/* ServerKeyExchange is needed. Prepare the message. */
@@ -3350,11 +3709,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
/* If there is a signature, write its length.
* ssl_prepare_server_key_exchange already wrote the signature
* itself at its proper place in the output buffer. */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED)
if( signature_len != 0 )
{
- ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
- ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len );
+ ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_1( signature_len );
+ ssl->out_msg[ssl->out_msglen++] = MBEDTLS_BYTE_0( signature_len );
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
ssl->out_msg + ssl->out_msglen,
@@ -3363,7 +3722,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
/* Skip over the already-written signature */
ssl->out_msglen += signature_len;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_SERVER_SIGNATURE_ENABLED */
/* Add header and send. */
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -3383,7 +3742,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) );
@@ -3487,7 +3846,7 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
size_t *peer_pmslen,
size_t peer_pmssize )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
size_t len = mbedtls_pk_get_len( public_key );
@@ -3510,12 +3869,13 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if ( p + 2 > end ) {
+ if ( p + 2 > end )
+ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
- if( *p++ != ( ( len >> 8 ) & 0xFF ) ||
- *p++ != ( ( len ) & 0xFF ) )
+ if( *p++ != MBEDTLS_BYTE_1( len ) ||
+ *p++ != MBEDTLS_BYTE_0( len ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3576,7 +3936,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
const unsigned char *end,
size_t pms_offset )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *pms = ssl->handshake->premaster + pms_offset;
unsigned char ver[2];
unsigned char fake_pms[48], peer_pms[48];
@@ -3617,16 +3977,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
diff |= peer_pms[1] ^ ver[1];
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
- /* MSVC has a warning about unary minus on unsigned, 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
- mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
-#if defined(_MSC_VER)
-#pragma warning( pop )
-#endif
+ mask = mbedtls_ct_uint_mask( diff );
/*
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
@@ -3668,16 +4019,14 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p,
const unsigned char *end )
{
int ret = 0;
- size_t n;
+ uint16_t n;
- if( ssl->conf->f_psk == NULL &&
- ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
- ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
+ if( ssl_conf_has_psk_or_cb( ssl->conf ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
@@ -3695,7 +4044,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
n = ( (*p)[0] << 8 ) | (*p)[1];
*p += 2;
- if( n < 1 || n > 65535 || n > (size_t) ( end - *p ) )
+ if( n == 0 || n > end - *p )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
@@ -3711,7 +4060,7 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
/* Identity is not a big secret since clients send it in the clear,
* but treat it carefully anyway, just in case */
if( n != ssl->conf->psk_identity_len ||
- mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
+ mbedtls_ct_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
{
ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
}
@@ -3729,15 +4078,15 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
unsigned char *p, *end;
- ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
@@ -3857,6 +4206,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* For opaque PSKs, we perform the PSK-to-MS derivation atomatically
+ * and skip the intermediate PMS. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "skip PMS generation for opaque PSK" ) );
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl,
ciphersuite_info->key_exchange ) ) != 0 )
{
@@ -3888,6 +4244,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret );
@@ -3917,6 +4279,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
if( p != end )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) );
@@ -3948,6 +4316,12 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Opaque PSKs are currently only supported for PSK-only. */
+ if( ssl_use_opaque_psk( ssl ) == 1 )
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+#endif
+
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_QP );
@@ -4011,24 +4385,15 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( 0 );
}
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
@@ -4038,7 +4403,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* !MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@@ -4051,21 +4416,33 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
#endif
mbedtls_md_type_t md_alg;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
+ ssl->handshake->ciphersuite_info;
+ mbedtls_pk_context * peer_pk;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
- ssl->session_negotiate->peer_cert == NULL )
+ if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+ ssl->state++;
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
+ ssl->state++;
+ return( 0 );
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( ssl->session_negotiate->peer_cert_digest == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Read the message without adding it to the checksum */
ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ );
@@ -4087,6 +4464,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
i = mbedtls_ssl_hs_hdr_len( ssl );
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ peer_pk = &ssl->handshake->peer_pubkey;
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ /* Should never happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ peer_pk = &ssl->session_negotiate->peer_cert->pk;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
/*
* struct {
* SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
@@ -4101,8 +4489,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
hashlen = 36;
/* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
- if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
- MBEDTLS_PK_ECDSA ) )
+ if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) )
{
hash_start += 16;
hashlen -= 16;
@@ -4157,7 +4544,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Check the certificate's key type matches the signature alg
*/
- if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
+ if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
@@ -4188,9 +4575,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
}
/* Calculate hash and verify signature */
- ssl->handshake->calc_verify( ssl, hash );
+ {
+ size_t dummy_hlen;
+ ssl->handshake->calc_verify( ssl, hash, &dummy_hlen );
+ }
- if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
+ if( ( ret = mbedtls_pk_verify( peer_pk,
md_alg, hash_start, hashlen,
ssl->in_msg + i, sig_len ) ) != 0 )
{
@@ -4204,17 +4594,12 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t tlen;
uint32_t lifetime;
@@ -4244,14 +4629,8 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )
tlen = 0;
}
- ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF;
- ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF;
- ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF;
- ssl->out_msg[7] = ( lifetime ) & 0xFF;
-
- ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF );
- ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF );
-
+ MBEDTLS_PUT_UINT32_BE( lifetime, ssl->out_msg, 4 );
+ MBEDTLS_PUT_UINT16_BE( tlen, ssl->out_msg, 8 );
ssl->out_msglen = 10 + tlen;
/*
diff --git a/thirdparty/mbedtls/library/ssl_ticket.c b/thirdparty/mbedtls/library/ssl_ticket.c
index bbde8e4ceb..046ed1b2ff 100644
--- a/thirdparty/mbedtls/library/ssl_ticket.c
+++ b/thirdparty/mbedtls/library/ssl_ticket.c
@@ -2,13 +2,7 @@
* TLS server tickets callbacks implementation
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TICKET_C)
@@ -62,6 +31,7 @@
#include "mbedtls/ssl_internal.h"
#include "mbedtls/ssl_ticket.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
#include <string.h>
@@ -99,7 +69,7 @@ void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx )
static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx,
unsigned char index )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MAX_KEY_BYTES];
mbedtls_ssl_ticket_key *key = ctx->keys + index;
@@ -159,7 +129,7 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
mbedtls_cipher_type_t cipher,
uint32_t lifetime )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
ctx->f_rng = f_rng;
@@ -180,11 +150,27 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 ||
- ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
- {
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ret = mbedtls_cipher_setup_psa( &ctx->keys[0].ctx,
+ cipher_info, TICKET_AUTH_TAG_BYTES );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ return( ret );
+ /* We don't yet expect to support all ciphers through PSA,
+ * so allow fallback to ordinary mbedtls_cipher_setup(). */
+ if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 )
+ return( ret );
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ ret = mbedtls_cipher_setup_psa( &ctx->keys[1].ctx,
+ cipher_info, TICKET_AUTH_TAG_BYTES );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ return( ret );
+ if( ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ if( ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 )
return( ret );
- }
if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 ||
( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 )
@@ -196,115 +182,6 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
}
/*
- * Serialize a session in the following format:
- * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
- * n . n+2 peer_cert length = m (0 if no certificate)
- * n+3 . n+2+m peer cert ASN.1
- */
-static int ssl_save_session( const mbedtls_ssl_session *session,
- unsigned char *buf, size_t buf_len,
- size_t *olen )
-{
- unsigned char *p = buf;
- size_t left = buf_len;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- if( left < sizeof( mbedtls_ssl_session ) )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-
- memcpy( p, session, sizeof( mbedtls_ssl_session ) );
- p += sizeof( mbedtls_ssl_session );
- left -= sizeof( mbedtls_ssl_session );
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert == NULL )
- cert_len = 0;
- else
- cert_len = session->peer_cert->raw.len;
-
- if( left < 3 + cert_len )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-
- *p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
- *p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
- *p++ = (unsigned char)( ( cert_len ) & 0xFF );
-
- if( session->peer_cert != NULL )
- memcpy( p, session->peer_cert->raw.p, cert_len );
-
- p += cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- *olen = p - buf;
-
- return( 0 );
-}
-
-/*
- * Unserialise session, see ssl_save_session()
- */
-static int ssl_load_session( mbedtls_ssl_session *session,
- const unsigned char *buf, size_t len )
-{
- const unsigned char *p = buf;
- const unsigned char * const end = buf + len;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- size_t cert_len;
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- memcpy( session, p, sizeof( mbedtls_ssl_session ) );
- p += sizeof( mbedtls_ssl_session );
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( 3 > (size_t)( end - p ) )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
- p += 3;
-
- if( cert_len == 0 )
- {
- session->peer_cert = NULL;
- }
- else
- {
- int ret;
-
- if( cert_len > (size_t)( end - p ) )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
-
- if( session->peer_cert == NULL )
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
-
- mbedtls_x509_crt_init( session->peer_cert );
-
- if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
- p, cert_len ) ) != 0 )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- session->peer_cert = NULL;
- return( ret );
- }
-
- p += cert_len;
- }
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
-
- if( p != end )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- return( 0 );
-}
-
-/*
* Create session ticket, with the following structure:
*
* struct {
@@ -325,14 +202,13 @@ int mbedtls_ssl_ticket_write( void *p_ticket,
size_t *tlen,
uint32_t *ticket_lifetime )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = start;
unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t clear_len, ciph_len;
*tlen = 0;
@@ -362,33 +238,33 @@ int mbedtls_ssl_ticket_write( void *p_ticket,
goto cleanup;
/* Dump session state */
- if( ( ret = ssl_save_session( session,
- state, end - state, &clear_len ) ) != 0 ||
+ if( ( ret = mbedtls_ssl_session_save( session,
+ state, end - state,
+ &clear_len ) ) != 0 ||
(unsigned long) clear_len > 65535 )
{
goto cleanup;
}
- state_len_bytes[0] = ( clear_len >> 8 ) & 0xff;
- state_len_bytes[1] = ( clear_len ) & 0xff;
+ MBEDTLS_PUT_UINT16_BE( clear_len, state_len_bytes, 0 );
/* Encrypt and authenticate */
- tag = state + clear_len;
- if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_encrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- state, clear_len, state, &ciph_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ state, clear_len,
+ state, end - state, &ciph_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
goto cleanup;
}
- if( ciph_len != clear_len )
+ if( ciph_len != clear_len + TICKET_AUTH_TAG_BYTES )
{
ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
goto cleanup;
}
- *tlen = TICKET_MIN_LEN + ciph_len;
+ *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
cleanup:
#if defined(MBEDTLS_THREADING_C)
@@ -423,14 +299,13 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
unsigned char *buf,
size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_ssl_ticket_context *ctx = p_ticket;
mbedtls_ssl_ticket_key *key;
unsigned char *key_name = buf;
unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
- unsigned char *tag;
size_t enc_len, clear_len;
if( ctx == NULL || ctx->f_rng == NULL )
@@ -448,7 +323,6 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
goto cleanup;
enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1];
- tag = ticket + enc_len;
if( len != TICKET_MIN_LEN + enc_len )
{
@@ -466,13 +340,13 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
}
/* Decrypt and authenticate */
- if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx,
+ if( ( ret = mbedtls_cipher_auth_decrypt_ext( &key->ctx,
iv, TICKET_IV_BYTES,
/* Additional data: key name, IV and length */
key_name, TICKET_ADD_DATA_LEN,
- ticket, enc_len,
- ticket, &clear_len,
- tag, TICKET_AUTH_TAG_BYTES ) ) != 0 )
+ ticket, enc_len + TICKET_AUTH_TAG_BYTES,
+ ticket, enc_len, &clear_len,
+ TICKET_AUTH_TAG_BYTES ) ) != 0 )
{
if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
ret = MBEDTLS_ERR_SSL_INVALID_MAC;
@@ -486,7 +360,7 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
}
/* Actually load session */
- if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 )
+ if( ( ret = mbedtls_ssl_session_load( session, ticket, clear_len ) ) != 0 )
goto cleanup;
#if defined(MBEDTLS_HAVE_TIME)
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index 127276486b..2e6469de83 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -2,13 +2,7 @@
* SSLv3/TLSv1 shared functions
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The SSL 3.0 specification was drafted by Netscape in 1996,
@@ -52,11 +25,7 @@
* http://www.ietf.org/rfc/rfc4346.txt
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SSL_TLS_C)
@@ -68,202 +37,120 @@
#define mbedtls_free free
#endif
-#include "mbedtls/debug.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h"
+#include "mbedtls/debug.h"
+#include "mbedtls/error.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/version.h"
+#include "mbedtls/constant_time.h"
#include <string.h>
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "mbedtls/psa_util.h"
+#include "psa/crypto.h"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/oid.h"
#endif
-static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl );
-static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl );
-
-/* Length of the "epoch" field in the record header */
-static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
-{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 2 );
-#else
- ((void) ssl);
-#endif
- return( 0 );
-}
-
-/*
- * Start a timer.
- * Passing millisecs = 0 cancels a running timer.
- */
-static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs )
-{
- if( ssl->f_set_timer == NULL )
- return;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) );
- ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs );
-}
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+/* Top-level Connection ID API */
-/*
- * Return -1 is timer is expired, 0 if it isn't.
- */
-static int ssl_check_timer( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf,
+ size_t len,
+ int ignore_other_cid )
{
- if( ssl->f_get_timer == NULL )
- return( 0 );
+ if( len > MBEDTLS_SSL_CID_IN_LEN_MAX )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ssl->f_get_timer( ssl->p_timer ) == 2 )
+ if( ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL &&
+ ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE )
{
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) );
- return( -1 );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
+ conf->ignore_unexpected_cid = ignore_other_cid;
+ conf->cid_len = len;
return( 0 );
}
-static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform );
-static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform );
-
-#define SSL_DONT_FORCE_FLUSH 0
-#define SSL_FORCE_FLUSH 1
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-/* Forward declarations for functions related to message buffering. */
-static void ssl_buffering_free( mbedtls_ssl_context *ssl );
-static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
- uint8_t slot );
-static void ssl_free_buffered_record( mbedtls_ssl_context *ssl );
-static int ssl_load_buffered_message( mbedtls_ssl_context *ssl );
-static int ssl_load_buffered_record( mbedtls_ssl_context *ssl );
-static int ssl_buffer_message( mbedtls_ssl_context *ssl );
-static int ssl_buffer_future_record( mbedtls_ssl_context *ssl );
-static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl );
-
-static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
-static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
-{
- size_t mtu = ssl_get_current_mtu( ssl );
-
- if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
- return( mtu );
-
- return( MBEDTLS_SSL_OUT_BUFFER_LEN );
-}
-
-static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
+int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl,
+ int enable,
+ unsigned char const *own_cid,
+ size_t own_cid_len )
{
- size_t const bytes_written = ssl->out_left;
- size_t const mtu = ssl_get_maximum_datagram_size( ssl );
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- /* Double-check that the write-index hasn't gone
- * past what we can transmit in a single datagram. */
- if( bytes_written > mtu )
+ ssl->negotiate_cid = enable;
+ if( enable == MBEDTLS_SSL_CID_DISABLED )
{
- /* Should never happen... */
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- return( (int) ( mtu - bytes_written ) );
-}
-
-static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl )
-{
- int ret;
- size_t remaining, expansion;
- size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
-
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
-
- if( max_len > mfl )
- max_len = mfl;
-
- /* By the standard (RFC 6066 Sect. 4), the MFL extension
- * only limits the maximum record payload size, so in theory
- * we would be allowed to pack multiple records of payload size
- * MFL into a single datagram. However, this would mean that there's
- * no way to explicitly communicate MTU restrictions to the peer.
- *
- * The following reduction of max_len makes sure that we never
- * write datagrams larger than MFL + Record Expansion Overhead.
- */
- if( max_len <= ssl->out_left )
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Disable use of CID extension." ) );
return( 0 );
+ }
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len );
- max_len -= ssl->out_left;
-#endif
-
- ret = ssl_get_remaining_space_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
- remaining = (size_t) ret;
-
- ret = mbedtls_ssl_get_record_expansion( ssl );
- if( ret < 0 )
- return( ret );
- expansion = (size_t) ret;
-
- if( remaining <= expansion )
- return( 0 );
+ if( own_cid_len != ssl->conf->cid_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config",
+ (unsigned) own_cid_len,
+ (unsigned) ssl->conf->cid_len ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
- remaining -= expansion;
- if( remaining >= max_len )
- remaining = max_len;
+ memcpy( ssl->own_cid, own_cid, own_cid_len );
+ /* Truncation is not an issue here because
+ * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */
+ ssl->own_cid_len = (uint8_t) own_cid_len;
- return( (int) remaining );
+ return( 0 );
}
-/*
- * Double the retransmit timeout value, within the allowed range,
- * returning -1 if the maximum value has already been reached.
- */
-static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl,
+ int *enabled,
+ unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ],
+ size_t *peer_cid_len )
{
- uint32_t new_timeout;
-
- if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max )
- return( -1 );
+ *enabled = MBEDTLS_SSL_CID_DISABLED;
- /* Implement the final paragraph of RFC 6347 section 4.1.1.1
- * in the following way: after the initial transmission and a first
- * retransmission, back off to a temporary estimated MTU of 508 bytes.
- * This value is guaranteed to be deliverable (if not guaranteed to be
- * delivered) of any compliant IPv4 (and IPv6) network, and should work
- * on most non-IP stacks too. */
- if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min )
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
- ssl->handshake->mtu = 508;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- new_timeout = 2 * ssl->handshake->retransmit_timeout;
+ /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions
+ * were used, but client and server requested the empty CID.
+ * This is indistinguishable from not using the CID extension
+ * in the first place. */
+ if( ssl->transform_in->in_cid_len == 0 &&
+ ssl->transform_in->out_cid_len == 0 )
+ {
+ return( 0 );
+ }
- /* Avoid arithmetic overflow and range overflow */
- if( new_timeout < ssl->handshake->retransmit_timeout ||
- new_timeout > ssl->conf->hs_timeout_max )
+ if( peer_cid_len != NULL )
{
- new_timeout = ssl->conf->hs_timeout_max;
+ *peer_cid_len = ssl->transform_in->out_cid_len;
+ if( peer_cid != NULL )
+ {
+ memcpy( peer_cid, ssl->transform_in->out_cid,
+ ssl->transform_in->out_cid_len );
+ }
}
- ssl->handshake->retransmit_timeout = new_timeout;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
+ *enabled = MBEDTLS_SSL_CID_ENABLED;
return( 0 );
}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl )
-{
- ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min;
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs",
- ssl->handshake->retransmit_timeout ) );
-}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
@@ -295,8 +182,8 @@ static unsigned int ssl_mfl_code_to_length( int mfl )
}
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
-#if defined(MBEDTLS_SSL_CLI_C)
-static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src )
+int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
+ const mbedtls_ssl_session *src )
{
mbedtls_ssl_session_free( dst );
memcpy( dst, src, sizeof( mbedtls_ssl_session ) );
@@ -306,9 +193,11 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C)
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( src->peer_cert != NULL )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) );
if( dst->peer_cert == NULL )
@@ -324,6 +213,21 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
return( ret );
}
}
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( src->peer_cert_digest != NULL )
+ {
+ dst->peer_cert_digest =
+ mbedtls_calloc( 1, src->peer_cert_digest_len );
+ if( dst->peer_cert_digest == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( dst->peer_cert_digest, src->peer_cert_digest,
+ src->peer_cert_digest_len );
+ dst->peer_cert_digest_type = src->peer_cert_digest_type;
+ dst->peer_cert_digest_len = src->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
@@ -339,22 +243,95 @@ static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session
return( 0 );
}
-#endif /* MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
-int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
- const unsigned char *key_enc, const unsigned char *key_dec,
- size_t keylen,
- const unsigned char *iv_enc, const unsigned char *iv_dec,
- size_t ivlen,
- const unsigned char *mac_enc, const unsigned char *mac_dec,
- size_t maclen ) = NULL;
-int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL;
-int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL;
-int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL;
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
+{
+ unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
+ if( resized_buffer == NULL )
+ return -1;
+
+ /* We want to copy len_new bytes when downsizing the buffer, and
+ * len_old bytes when upsizing, so we choose the smaller of two sizes,
+ * to fit one buffer into another. Size checks, ensuring that no data is
+ * lost, are done outside of this function. */
+ memcpy( resized_buffer, *buffer,
+ ( len_new < *len_old ) ? len_new : *len_old );
+ mbedtls_platform_zeroize( *buffer, *len_old );
+ mbedtls_free( *buffer );
+
+ *buffer = resized_buffer;
+ *len_old = len_new;
+
+ return 0;
+}
+
+static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing,
+ size_t in_buf_new_len,
+ size_t out_buf_new_len )
+{
+ int modified = 0;
+ size_t written_in = 0, iv_offset_in = 0, len_offset_in = 0;
+ size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
+ if( ssl->in_buf != NULL )
+ {
+ written_in = ssl->in_msg - ssl->in_buf;
+ iv_offset_in = ssl->in_iv - ssl->in_buf;
+ len_offset_in = ssl->in_len - ssl->in_buf;
+ if( downsizing ?
+ ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len :
+ ssl->in_buf_len < in_buf_new_len )
+ {
+ if( resize_buffer( &ssl->in_buf, in_buf_new_len, &ssl->in_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %" MBEDTLS_PRINTF_SIZET,
+ in_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+
+ if( ssl->out_buf != NULL )
+ {
+ written_out = ssl->out_msg - ssl->out_buf;
+ iv_offset_out = ssl->out_iv - ssl->out_buf;
+ len_offset_out = ssl->out_len - ssl->out_buf;
+ if( downsizing ?
+ ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len :
+ ssl->out_buf_len < out_buf_new_len )
+ {
+ if( resize_buffer( &ssl->out_buf, out_buf_new_len, &ssl->out_buf_len ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %" MBEDTLS_PRINTF_SIZET,
+ out_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+ if( modified )
+ {
+ /* Update pointers here to avoid doing it twice. */
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+ /* Fields below might not be properly updated with record
+ * splitting or with CID, so they are manually updated here. */
+ ssl->out_msg = ssl->out_buf + written_out;
+ ssl->out_len = ssl->out_buf + len_offset_out;
+ ssl->out_iv = ssl->out_buf + iv_offset_out;
+
+ ssl->in_msg = ssl->in_buf + written_in;
+ ssl->in_len = ssl->in_buf + len_offset_in;
+ ssl->in_iv = ssl->in_buf + iv_offset_in;
+ }
+}
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
/*
* Key material generation
@@ -429,16 +406,22 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
size_t nb, hs;
size_t i, j, k;
const unsigned char *S1, *S2;
- unsigned char tmp[128];
+ unsigned char *tmp;
+ size_t tmp_len = 0;
unsigned char h_i[20];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_init( &md_ctx );
- if( sizeof( tmp ) < 20 + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ tmp_len = 20 + strlen( label ) + rlen;
+ tmp = mbedtls_calloc( 1, tmp_len );
+ if( tmp == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
hs = ( slen + 1 ) / 2;
S1 = secret;
@@ -459,7 +442,9 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+ {
goto exit;
+ }
ret = mbedtls_md_hmac_starts( &md_ctx, S1, hs );
if( ret != 0 )
@@ -511,7 +496,9 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
}
if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 )
+ {
goto exit;
+ }
ret = mbedtls_md_hmac_starts( &md_ctx, S2, hs );
if( ret != 0 )
@@ -554,14 +541,144 @@ static int tls1_prf( const unsigned char *secret, size_t slen,
exit:
mbedtls_md_free( &md_ctx );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
+ mbedtls_free( tmp );
+ return( ret );
}
#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+static psa_status_t setup_psa_key_derivation( psa_key_derivation_operation_t* derivation,
+ psa_key_id_t key,
+ psa_algorithm_t alg,
+ const unsigned char* seed, size_t seed_length,
+ const unsigned char* label, size_t label_length,
+ size_t capacity )
+{
+ psa_status_t status;
+
+ status = psa_key_derivation_setup( derivation, alg );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ if( PSA_ALG_IS_TLS12_PRF( alg ) || PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) )
+ {
+ status = psa_key_derivation_input_bytes( derivation,
+ PSA_KEY_DERIVATION_INPUT_SEED,
+ seed, seed_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ if( mbedtls_svc_key_id_is_null( key ) )
+ {
+ status = psa_key_derivation_input_bytes(
+ derivation, PSA_KEY_DERIVATION_INPUT_SECRET,
+ NULL, 0 );
+ }
+ else
+ {
+ status = psa_key_derivation_input_key(
+ derivation, PSA_KEY_DERIVATION_INPUT_SECRET, key );
+ }
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ status = psa_key_derivation_input_bytes( derivation,
+ PSA_KEY_DERIVATION_INPUT_LABEL,
+ label, label_length );
+ if( status != PSA_SUCCESS )
+ return( status );
+ }
+ else
+ {
+ return( PSA_ERROR_NOT_SUPPORTED );
+ }
+
+ status = psa_key_derivation_set_capacity( derivation, capacity );
+ if( status != PSA_SUCCESS )
+ return( status );
+
+ return( PSA_SUCCESS );
+}
+
+static int tls_prf_generic( mbedtls_md_type_t md_type,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen )
+{
+ psa_status_t status;
+ psa_algorithm_t alg;
+ psa_key_id_t master_key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_derivation_operation_t derivation =
+ PSA_KEY_DERIVATION_OPERATION_INIT;
+
+ if( md_type == MBEDTLS_MD_SHA384 )
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_384);
+ else
+ alg = PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256);
+
+ /* Normally a "secret" should be long enough to be impossible to
+ * find by brute force, and in particular should not be empty. But
+ * this PRF is also used to derive an IV, in particular in EAP-TLS,
+ * and for this use case it makes sense to have a 0-length "secret".
+ * Since the key API doesn't allow importing a key of length 0,
+ * keep master_key=0, which setup_psa_key_derivation() understands
+ * to mean a 0-length "secret" input. */
+ if( slen != 0 )
+ {
+ psa_key_attributes_t key_attributes = psa_key_attributes_init();
+ psa_set_key_usage_flags( &key_attributes, PSA_KEY_USAGE_DERIVE );
+ psa_set_key_algorithm( &key_attributes, alg );
+ psa_set_key_type( &key_attributes, PSA_KEY_TYPE_DERIVE );
+
+ status = psa_import_key( &key_attributes, secret, slen, &master_key );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = setup_psa_key_derivation( &derivation,
+ master_key, alg,
+ random, rlen,
+ (unsigned char const *) label,
+ (size_t) strlen( label ),
+ dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_output_bytes( &derivation, dstbuf, dlen );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_abort( &derivation );
+ if( status != PSA_SUCCESS )
+ {
+ psa_destroy_key( master_key );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ if( ! mbedtls_svc_key_id_is_null( master_key ) )
+ status = psa_destroy_key( master_key );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+
+ return( 0 );
+}
+
+#else /* MBEDTLS_USE_PSA_CRYPTO */
+
static int tls_prf_generic( mbedtls_md_type_t md_type,
const unsigned char *secret, size_t slen,
const char *label,
@@ -570,11 +687,12 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
{
size_t nb;
size_t i, j, k, md_len;
- unsigned char tmp[128];
+ unsigned char *tmp;
+ size_t tmp_len = 0;
unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_md_init( &md_ctx );
@@ -583,8 +701,13 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
md_len = mbedtls_md_get_size( md_info );
- if( sizeof( tmp ) < md_len + strlen( label ) + rlen )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ tmp_len = md_len + strlen( label ) + rlen;
+ tmp = mbedtls_calloc( 1, tmp_len );
+ if( tmp == NULL )
+ {
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
nb = strlen( label );
memcpy( tmp + md_len, label, nb );
@@ -638,12 +761,14 @@ static int tls_prf_generic( mbedtls_md_type_t md_type,
exit:
mbedtls_md_free( &md_ctx );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ mbedtls_platform_zeroize( tmp, tmp_len );
mbedtls_platform_zeroize( h_i, sizeof( h_i ) );
- return( 0 );
-}
+ mbedtls_free( tmp );
+ return( ret );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
#if defined(MBEDTLS_SHA256_C)
static int tls_prf_sha256( const unsigned char *secret, size_t slen,
const char *label,
@@ -655,7 +780,7 @@ static int tls_prf_sha256( const unsigned char *secret, size_t slen,
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static int tls_prf_sha384( const unsigned char *secret, size_t slen,
const char *label,
const unsigned char *random, size_t rlen,
@@ -664,7 +789,7 @@ static int tls_prf_sha384( const unsigned char *secret, size_t slen,
return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen,
label, random, rlen, dstbuf, dlen ) );
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t );
@@ -675,207 +800,265 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned c
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3)
-static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_ssl( const mbedtls_ssl_context *, unsigned char *, size_t * );
static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int );
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls( const mbedtls_ssl_context *, unsigned char*, size_t * );
static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int );
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *,unsigned char*, size_t * );
static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t );
-static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * );
+static void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *, unsigned char*, size_t * );
static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int );
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl )
{
- int ret = 0;
- unsigned char tmp[64];
- unsigned char keyblk[256];
- unsigned char *key1;
- unsigned char *key2;
- unsigned char *mac_enc;
- unsigned char *mac_dec;
- size_t mac_key_len;
- size_t iv_copy_len;
- const mbedtls_cipher_info_t *cipher_info;
- const mbedtls_md_info_t *md_info;
-
- mbedtls_ssl_session *session = ssl->session_negotiate;
- mbedtls_ssl_transform *transform = ssl->transform_negotiate;
- mbedtls_ssl_handshake_params *handshake = ssl->handshake;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
-
- cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
- if( cipher_info == NULL )
+ if( ssl->conf->f_psk != NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
- transform->ciphersuite_info->cipher ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
+ /* If we've used a callback to select the PSK,
+ * the static configuration is irrelevant. */
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ return( 1 );
- md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
- if( md_info == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
- transform->ciphersuite_info->mac ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ return( 0 );
}
- /*
- * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions
- */
+ if( ! mbedtls_svc_key_id_is_null( ssl->conf->psk_opaque ) )
+ return( 1 );
+
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO &&
+ MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */
+
+#if defined(MBEDTLS_SSL_EXPORT_KEYS)
+static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf )
+{
#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ if( tls_prf == ssl3_prf )
{
- handshake->tls_prf = ssl3_prf;
- handshake->calc_verify = ssl_calc_verify_ssl;
- handshake->calc_finished = ssl_calc_finished_ssl;
+ return( MBEDTLS_SSL_TLS_PRF_SSL3 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( tls_prf == tls1_prf )
{
- handshake->tls_prf = tls1_prf;
- handshake->calc_verify = ssl_calc_verify_tls;
- handshake->calc_finished = ssl_calc_finished_tls;
+ return( MBEDTLS_SSL_TLS_PRF_TLS1 );
}
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
- transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ if( tls_prf == tls_prf_sha384 )
{
- handshake->tls_prf = tls_prf_sha384;
- handshake->calc_verify = ssl_calc_verify_tls_sha384;
- handshake->calc_finished = ssl_calc_finished_tls_sha384;
+ return( MBEDTLS_SSL_TLS_PRF_SHA384 );
}
else
#endif
#if defined(MBEDTLS_SHA256_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( tls_prf == tls_prf_sha256 )
{
- handshake->tls_prf = tls_prf_sha256;
- handshake->calc_verify = ssl_calc_verify_tls_sha256;
- handshake->calc_finished = ssl_calc_finished_tls_sha256;
+ return( MBEDTLS_SSL_TLS_PRF_SHA256 );
}
else
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
+ return( MBEDTLS_SSL_TLS_PRF_NONE );
+}
+#endif /* MBEDTLS_SSL_EXPORT_KEYS */
- /*
- * SSLv3:
- * master =
- * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) +
- * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) )
- *
- * TLSv1+:
- * master = PRF( premaster, "master secret", randbytes )[0..47]
- */
- if( handshake->resume == 0 )
+int mbedtls_ssl_tls_prf( const mbedtls_tls_prf_types prf,
+ const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen )
+{
+ mbedtls_ssl_tls_prf_cb *tls_prf = NULL;
+
+ switch( prf )
{
- MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster,
- handshake->pmslen );
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ case MBEDTLS_SSL_TLS_PRF_SSL3:
+ tls_prf = ssl3_prf;
+ break;
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ case MBEDTLS_SSL_TLS_PRF_TLS1:
+ tls_prf = tls1_prf;
+ break;
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
- if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
- {
- unsigned char session_hash[48];
- size_t hash_len;
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ case MBEDTLS_SSL_TLS_PRF_SHA384:
+ tls_prf = tls_prf_sha384;
+ break;
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
+#if defined(MBEDTLS_SHA256_C)
+ case MBEDTLS_SSL_TLS_PRF_SHA256:
+ tls_prf = tls_prf_sha256;
+ break;
+#endif /* MBEDTLS_SHA256_C */
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ default:
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) );
+ return( tls_prf( secret, slen, label, random, rlen, dstbuf, dlen ) );
+}
- ssl->handshake->calc_verify( ssl, session_hash );
+/* Type for the TLS PRF */
+typedef int ssl_tls_prf_t(const unsigned char *, size_t, const char *,
+ const unsigned char *, size_t,
+ unsigned char *, size_t);
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
- {
-#if defined(MBEDTLS_SHA512_C)
- if( ssl->transform_negotiate->ciphersuite_info->mac ==
- MBEDTLS_MD_SHA384 )
- {
- hash_len = 48;
- }
- else
+/*
+ * Populate a transform structure with session keys and all the other
+ * necessary information.
+ *
+ * Parameters:
+ * - [in/out]: transform: structure to populate
+ * [in] must be just initialised with mbedtls_ssl_transform_init()
+ * [out] fully populated, ready for use by mbedtls_ssl_{en,de}crypt_buf()
+ * - [in] ciphersuite
+ * - [in] master
+ * - [in] encrypt_then_mac
+ * - [in] trunc_hmac
+ * - [in] compression
+ * - [in] tls_prf: pointer to PRF to use for key derivation
+ * - [in] randbytes: buffer holding ServerHello.random + ClientHello.random
+ * - [in] minor_ver: SSL/TLS minor version
+ * - [in] endpoint: client or server
+ * - [in] ssl: optionally used for:
+ * - MBEDTLS_SSL_HW_RECORD_ACCEL: whole context (non-const)
+ * - MBEDTLS_SSL_EXPORT_KEYS: ssl->conf->{f,p}_export_keys
+ * - MBEDTLS_DEBUG_C: ssl->conf->{f,p}_dbg
+ */
+static int ssl_populate_transform( mbedtls_ssl_transform *transform,
+ int ciphersuite,
+ const unsigned char master[48],
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ int encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ int trunc_hmac,
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ int compression,
#endif
- hash_len = 32;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- hash_len = 36;
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len );
+ ssl_tls_prf_t tls_prf,
+ const unsigned char randbytes[64],
+ int minor_ver,
+ unsigned endpoint,
+#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ const
+#endif
+ mbedtls_ssl_context *ssl )
+{
+ int ret = 0;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ int psa_fallthrough;
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+ unsigned char keyblk[256];
+ unsigned char *key1;
+ unsigned char *key2;
+ unsigned char *mac_enc;
+ unsigned char *mac_dec;
+ size_t mac_key_len = 0;
+ size_t iv_copy_len;
+ unsigned keylen;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ const mbedtls_cipher_info_t *cipher_info;
+ const mbedtls_md_info_t *md_info;
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "extended master secret",
- session_hash, hash_len,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
+#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
+ !defined(MBEDTLS_SSL_EXPORT_KEYS) && \
+ !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for those cases */
+ (void) ssl;
+#endif
- }
- else
+ /*
+ * Some data just needs copying into the structure
+ */
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \
+ defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ transform->encrypt_then_mac = encrypt_then_mac;
#endif
- ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
- "master secret",
- handshake->randbytes, 64,
- session->master, 48 );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
- return( ret );
- }
+ transform->minor_ver = minor_ver;
- mbedtls_platform_zeroize( handshake->premaster,
- sizeof(handshake->premaster) );
- }
- else
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+ memcpy( transform->randbytes, randbytes, sizeof( transform->randbytes ) );
+#endif
/*
- * Swap the client and server random values.
+ * Get various info structures
*/
- memcpy( tmp, handshake->randbytes, 64 );
- memcpy( handshake->randbytes, tmp + 32, 32 );
- memcpy( handshake->randbytes + 32, tmp, 32 );
- mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
+ if( ciphersuite_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %d not found",
+ ciphersuite ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+ if( cipher_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %u not found",
+ ciphersuite_info->cipher ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
+ if( md_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %u not found",
+ (unsigned) ciphersuite_info->mac ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* Copy own and peer's CID if the use of the CID
+ * extension has been negotiated. */
+ if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) );
+
+ transform->in_cid_len = ssl->own_cid_len;
+ memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid,
+ transform->in_cid_len );
+
+ transform->out_cid_len = ssl->handshake->peer_cid_len;
+ memcpy( transform->out_cid, ssl->handshake->peer_cid,
+ ssl->handshake->peer_cid_len );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid,
+ transform->out_cid_len );
+ }
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
/*
- * SSLv3:
- * key block =
- * MD5( master + SHA1( 'A' + master + randbytes ) ) +
- * MD5( master + SHA1( 'BB' + master + randbytes ) ) +
- * MD5( master + SHA1( 'CCC' + master + randbytes ) ) +
- * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) +
- * ...
- *
- * TLSv1:
- * key block = PRF( master, "key expansion", randbytes )
+ * Compute key block using the PRF
*/
- ret = handshake->tls_prf( session->master, 48, "key expansion",
- handshake->randbytes, 64, keyblk, 256 );
+ ret = tls_prf( master, 48, "key expansion", randbytes, 64, keyblk, 256 );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
@@ -883,56 +1066,70 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s",
- mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 );
- MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 );
+ mbedtls_ssl_get_ciphersuite_name( ciphersuite ) ) );
+ MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", master, 48 );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", randbytes, 64 );
MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 );
- mbedtls_platform_zeroize( handshake->randbytes,
- sizeof( handshake->randbytes ) );
-
/*
* Determine the appropriate key, IV and MAC length.
*/
- transform->keylen = cipher_info->key_bitlen / 8;
+ keylen = cipher_info->key_bitlen / 8;
+#if defined(MBEDTLS_GCM_C) || \
+ defined(MBEDTLS_CCM_C) || \
+ defined(MBEDTLS_CHACHAPOLY_C)
if( cipher_info->mode == MBEDTLS_MODE_GCM ||
cipher_info->mode == MBEDTLS_MODE_CCM ||
cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
{
- size_t taglen, explicit_ivlen;
+ size_t explicit_ivlen;
transform->maclen = 0;
mac_key_len = 0;
-
- /* All modes haves 96-bit IVs;
- * GCM and CCM has 4 implicit and 8 explicit bytes
- * ChachaPoly has all 12 bytes implicit
+ transform->taglen =
+ ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
+
+ /* All modes haves 96-bit IVs, but the length of the static parts vary
+ * with mode and version:
+ * - For GCM and CCM in TLS 1.2, there's a static IV of 4 Bytes
+ * (to be concatenated with a dynamically chosen IV of 8 Bytes)
+ * - For ChaChaPoly in TLS 1.2, and all modes in TLS 1.3, there's
+ * a static IV of 12 Bytes (to be XOR'ed with the 8 Byte record
+ * sequence number).
*/
transform->ivlen = 12;
- if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_4 )
+ {
transform->fixed_ivlen = 12;
+ }
else
- transform->fixed_ivlen = 4;
-
- /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */
- taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
-
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
+ {
+ if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
+ transform->fixed_ivlen = 12;
+ else
+ transform->fixed_ivlen = 4;
+ }
/* Minimum length of encrypted record */
explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
- transform->minlen = explicit_ivlen + taglen;
+ transform->minlen = explicit_ivlen + transform->taglen;
}
else
+#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C */
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+ if( cipher_info->mode == MBEDTLS_MODE_STREAM ||
+ cipher_info->mode == MBEDTLS_MODE_CBC )
{
/* Initialize HMAC contexts */
if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 ||
( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret );
- return( ret );
+ goto end;
}
/* Get MAC length */
@@ -945,7 +1142,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* (rfc 6066 page 13 or rfc 2104 section 4),
* so we only need to adjust the length here.
*/
- if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
+ if( trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED )
{
transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN;
@@ -973,7 +1170,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
* 2. IV except for SSL3 and TLS 1.0
*/
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
+ if( encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
{
transform->minlen = transform->maclen
+ cipher_info->block_size;
@@ -987,14 +1184,14 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ||
+ minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 )
; /* No need to adjust minlen */
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 ||
+ minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
transform->minlen += transform->ivlen;
}
@@ -1002,23 +1199,32 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
}
}
+ else
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d",
- transform->keylen, transform->minlen, transform->ivlen,
- transform->maclen ) );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %u, minlen: %u, ivlen: %u, maclen: %u",
+ (unsigned) keylen,
+ (unsigned) transform->minlen,
+ (unsigned) transform->ivlen,
+ (unsigned) transform->maclen ) );
/*
* Finally setup the cipher contexts, IVs and MAC secrets.
*/
#if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ if( endpoint == MBEDTLS_SSL_IS_CLIENT )
{
key1 = keyblk + mac_key_len * 2;
- key2 = keyblk + mac_key_len * 2 + transform->keylen;
+ key2 = keyblk + mac_key_len * 2 + keylen;
mac_enc = keyblk;
mac_dec = keyblk + mac_key_len;
@@ -1028,16 +1234,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
*/
iv_copy_len = ( transform->fixed_ivlen ) ?
transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len,
+ memcpy( transform->iv_enc, key2 + keylen, iv_copy_len );
+ memcpy( transform->iv_dec, key2 + keylen + iv_copy_len,
iv_copy_len );
}
else
#endif /* MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
+ if( endpoint == MBEDTLS_SSL_IS_SERVER )
{
- key1 = keyblk + mac_key_len * 2 + transform->keylen;
+ key1 = keyblk + mac_key_len * 2 + keylen;
key2 = keyblk + mac_key_len * 2;
mac_enc = keyblk + mac_key_len;
@@ -1048,24 +1254,27 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
*/
iv_copy_len = ( transform->fixed_ivlen ) ?
transform->fixed_ivlen : transform->ivlen;
- memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len );
- memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len,
+ memcpy( transform->iv_dec, key1 + keylen, iv_copy_len );
+ memcpy( transform->iv_enc, key1 + keylen + iv_copy_len,
iv_copy_len );
}
else
#endif /* MBEDTLS_SSL_SRV_C */
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if( mac_key_len > sizeof transform->mac_enc )
+ if( mac_key_len > sizeof( transform->mac_enc ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
memcpy( transform->mac_enc, mac_enc, mac_key_len );
@@ -1075,7 +1284,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
+ if( minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
{
/* For HMAC-based ciphersuites, initialize the HMAC transforms.
For AEAD-based ciphersuites, there is nothing to do here. */
@@ -1084,59 +1293,151 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
ret = mbedtls_md_hmac_starts( &transform->md_ctx_enc,
mac_enc, mac_key_len );
if( ret != 0 )
- return( ret );
+ goto end;
ret = mbedtls_md_hmac_starts( &transform->md_ctx_dec,
mac_dec, mac_key_len );
if( ret != 0 )
- return( ret );
+ goto end;
}
}
else
#endif
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ goto end;
}
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_init != NULL )
{
+ ret = 0;
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
- if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
+ if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, keylen,
transform->iv_enc, transform->iv_dec,
iv_copy_len,
mac_enc, mac_dec,
mac_key_len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ ret = MBEDTLS_ERR_SSL_HW_ACCEL_FAILED;
+ goto end;
}
}
+#else
+ ((void) mac_dec);
+ ((void) mac_enc);
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( ssl->conf->f_export_keys != NULL )
{
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
- session->master, keyblk,
- mac_key_len, transform->keylen,
+ master, keyblk,
+ mac_key_len, keylen,
iv_copy_len );
}
+
+ if( ssl->conf->f_export_keys_ext != NULL )
+ {
+ ssl->conf->f_export_keys_ext( ssl->conf->p_export_keys,
+ master, keyblk,
+ mac_key_len, keylen,
+ iv_copy_len,
+ randbytes + 32,
+ randbytes,
+ tls_prf_get_type( tls_prf ) );
+ }
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+
+ /* Only use PSA-based ciphers for TLS-1.2.
+ * That's relevant at least for TLS-1.0, where
+ * we assume that mbedtls_cipher_crypt() updates
+ * the structure field for the IV, which the PSA-based
+ * implementation currently doesn't. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_enc,
+ cipher_info, transform->taglen );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+ goto end;
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based encryption cipher context" ) );
+ psa_fallthrough = 0;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record encryption - fall through to default setup." ) );
+ psa_fallthrough = 1;
+ }
+ }
+ else
+ psa_fallthrough = 1;
+#else
+ psa_fallthrough = 1;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+
+ if( psa_fallthrough == 1 )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
+ goto end;
+ }
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ /* Only use PSA-based ciphers for TLS-1.2.
+ * That's relevant at least for TLS-1.0, where
+ * we assume that mbedtls_cipher_crypt() updates
+ * the structure field for the IV, which the PSA-based
+ * implementation currently doesn't. */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ ret = mbedtls_cipher_setup_psa( &transform->cipher_ctx_dec,
+ cipher_info, transform->taglen );
+ if( ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup_psa", ret );
+ goto end;
+ }
+
+ if( ret == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Successfully setup PSA-based decryption cipher context" ) );
+ psa_fallthrough = 0;
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to setup PSA-based cipher context for record decryption - fall through to default setup." ) );
+ psa_fallthrough = 1;
+ }
}
+ else
+ psa_fallthrough = 1;
+#else
+ psa_fallthrough = 1;
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ if( psa_fallthrough == 1 )
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
cipher_info ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1,
@@ -1144,7 +1445,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_ENCRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2,
@@ -1152,7 +1453,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_DECRYPT ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
- return( ret );
+ goto end;
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
@@ -1162,37 +1463,23 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
+ goto end;
}
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec,
MBEDTLS_PADDING_NONE ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
- return( ret );
+ goto end;
}
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
- mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+ /* Initialize Zlib contexts */
#if defined(MBEDTLS_ZLIB_SUPPORT)
- // Initialize compression
- //
- if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
+ if( compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
{
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
- ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
- if( ssl->compress_buf == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
- }
-
MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) );
memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) );
@@ -1203,18 +1490,317 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
inflateInit( &transform->ctx_inflate ) != Z_OK )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
+ ret = MBEDTLS_ERR_SSL_COMPRESSION_FAILED;
+ goto end;
}
}
#endif /* MBEDTLS_ZLIB_SUPPORT */
+end:
+ mbedtls_platform_zeroize( keyblk, sizeof( keyblk ) );
+ return( ret );
+}
+
+/*
+ * Set appropriate PRF function and other SSL / TLS 1.0/1.1 / TLS1.2 functions
+ *
+ * Inputs:
+ * - SSL/TLS minor version
+ * - hash associated with the ciphersuite (only used by TLS 1.2)
+ *
+ * Outputs:
+ * - the tls_prf, calc_verify and calc_finished members of handshake structure
+ */
+static int ssl_set_handshake_prfs( mbedtls_ssl_handshake_params *handshake,
+ int minor_ver,
+ mbedtls_md_type_t hash )
+{
+#if !defined(MBEDTLS_SSL_PROTO_TLS1_2) || \
+ !( defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384) )
+ (void) hash;
+#endif
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
+ {
+ handshake->tls_prf = ssl3_prf;
+ handshake->calc_verify = ssl_calc_verify_ssl;
+ handshake->calc_finished = ssl_calc_finished_ssl;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ if( minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ handshake->tls_prf = tls1_prf;
+ handshake->calc_verify = ssl_calc_verify_tls;
+ handshake->calc_finished = ssl_calc_finished_tls;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ hash == MBEDTLS_MD_SHA384 )
+ {
+ handshake->tls_prf = tls_prf_sha384;
+ handshake->calc_verify = ssl_calc_verify_tls_sha384;
+ handshake->calc_finished = ssl_calc_finished_tls_sha384;
+ }
+ else
+#endif
+#if defined(MBEDTLS_SHA256_C)
+ if( minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ handshake->tls_prf = tls_prf_sha256;
+ handshake->calc_verify = ssl_calc_verify_tls_sha256;
+ handshake->calc_finished = ssl_calc_finished_tls_sha256;
+ }
+ else
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ {
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compute master secret if needed
+ *
+ * Parameters:
+ * [in/out] handshake
+ * [in] resume, premaster, extended_ms, calc_verify, tls_prf
+ * (PSA-PSK) ciphersuite_info, psk_opaque
+ * [out] premaster (cleared)
+ * [out] master
+ * [in] ssl: optionally used for debugging, EMS and PSA-PSK
+ * debug: conf->f_dbg, conf->p_dbg
+ * EMS: passed to calc_verify (debug + (SSL3) session_negotiate)
+ * PSA-PSA: minor_ver, conf
+ */
+static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake,
+ unsigned char *master,
+ const mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* cf. RFC 5246, Section 8.1:
+ * "The master secret is always exactly 48 bytes in length." */
+ size_t const master_secret_len = 48;
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ unsigned char session_hash[48];
+#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+
+ /* The label for the KDF used for key expansion.
+ * This is either "master secret" or "extended master secret"
+ * depending on whether the Extended Master Secret extension
+ * is used. */
+ char const *lbl = "master secret";
+
+ /* The salt for the KDF used for key expansion.
+ * - If the Extended Master Secret extension is not used,
+ * this is ClientHello.Random + ServerHello.Random
+ * (see Sect. 8.1 in RFC 5246).
+ * - If the Extended Master Secret extension is used,
+ * this is the transcript of the handshake so far.
+ * (see Sect. 4 in RFC 7627). */
+ unsigned char const *salt = handshake->randbytes;
+ size_t salt_len = 64;
+
+#if !defined(MBEDTLS_DEBUG_C) && \
+ !defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) && \
+ !(defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED))
+ ssl = NULL; /* make sure we don't use it except for those cases */
+ (void) ssl;
+#endif
+
+ if( handshake->resume != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) );
+ return( 0 );
+ }
+
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+ if( handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED )
+ {
+ lbl = "extended master secret";
+ salt = session_hash;
+ handshake->calc_verify( ssl, session_hash, &salt_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "session hash for extended master secret",
+ session_hash, salt_len );
+ }
+#endif /* MBEDTLS_SSL_EXTENDED_MS_ENABLED */
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO) && \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
+ if( handshake->ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK &&
+ ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
+ ssl_use_opaque_psk( ssl ) == 1 )
+ {
+ /* Perform PSK-to-MS expansion in a single step. */
+ psa_status_t status;
+ psa_algorithm_t alg;
+ psa_key_id_t psk;
+ psa_key_derivation_operation_t derivation =
+ PSA_KEY_DERIVATION_OPERATION_INIT;
+ mbedtls_md_type_t hash_alg = handshake->ciphersuite_info->mac;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "perform PSA-based PSK-to-MS expansion" ) );
+
+ psk = mbedtls_ssl_get_opaque_psk( ssl );
+
+ if( hash_alg == MBEDTLS_MD_SHA384 )
+ alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_384);
+ else
+ alg = PSA_ALG_TLS12_PSK_TO_MS(PSA_ALG_SHA_256);
+
+ status = setup_psa_key_derivation( &derivation, psk, alg,
+ salt, salt_len,
+ (unsigned char const *) lbl,
+ (size_t) strlen( lbl ),
+ master_secret_len );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_output_bytes( &derivation,
+ master,
+ master_secret_len );
+ if( status != PSA_SUCCESS )
+ {
+ psa_key_derivation_abort( &derivation );
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+
+ status = psa_key_derivation_abort( &derivation );
+ if( status != PSA_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ }
+ else
+#endif
+ {
+ ret = handshake->tls_prf( handshake->premaster, handshake->pmslen,
+ lbl, salt, salt_len,
+ master,
+ master_secret_len );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret );
+ return( ret );
+ }
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret",
+ handshake->premaster,
+ handshake->pmslen );
+
+ mbedtls_platform_zeroize( handshake->premaster,
+ sizeof(handshake->premaster) );
+ }
+
+ return( 0 );
+}
+
+int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
+
+ /* Set PRF, calc_verify and calc_finished function pointers */
+ ret = ssl_set_handshake_prfs( ssl->handshake,
+ ssl->minor_ver,
+ ciphersuite_info->mac );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_set_handshake_prfs", ret );
+ return( ret );
+ }
+
+ /* Compute master secret if needed */
+ ret = ssl_compute_master( ssl->handshake,
+ ssl->session_negotiate->master,
+ ssl );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compute_master", ret );
+ return( ret );
+ }
+
+ /* Swap the client and server random values:
+ * - MS derivation wanted client+server (RFC 5246 8.1)
+ * - key derivation wants server+client (RFC 5246 6.3) */
+ {
+ unsigned char tmp[64];
+ memcpy( tmp, ssl->handshake->randbytes, 64 );
+ memcpy( ssl->handshake->randbytes, tmp + 32, 32 );
+ memcpy( ssl->handshake->randbytes + 32, tmp, 32 );
+ mbedtls_platform_zeroize( tmp, sizeof( tmp ) );
+ }
+
+ /* Populate transform structure */
+ ret = ssl_populate_transform( ssl->transform_negotiate,
+ ssl->session_negotiate->ciphersuite,
+ ssl->session_negotiate->master,
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ ssl->session_negotiate->encrypt_then_mac,
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ ssl->session_negotiate->trunc_hmac,
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ ssl->session_negotiate->compression,
+#endif
+ ssl->handshake->tls_prf,
+ ssl->handshake->randbytes,
+ ssl->minor_ver,
+ ssl->conf->endpoint,
+ ssl );
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "ssl_populate_transform", ret );
+ return( ret );
+ }
+
+ /* We no longer need Server/ClientHello.random values */
+ mbedtls_platform_zeroize( ssl->handshake->randbytes,
+ sizeof( ssl->handshake->randbytes ) );
+
+ /* Allocate compression buffer */
+#if defined(MBEDTLS_ZLIB_SUPPORT)
+ if( ssl->session_negotiate->compression == MBEDTLS_SSL_COMPRESS_DEFLATE &&
+ ssl->compress_buf == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) );
+ ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN );
+ if( ssl->compress_buf == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+ MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+ }
+#endif
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) );
return( 0 );
}
#if defined(MBEDTLS_SSL_PROTO_SSL3)
-void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_ssl( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
@@ -1252,7 +1838,9 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha1_update_ret( &sha1, hash + 16, 20 );
mbedtls_sha1_finish_ret( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+ *hlen = 36;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_md5_free( &md5 );
@@ -1263,7 +1851,9 @@ void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char *hash )
#endif /* MBEDTLS_SSL_PROTO_SSL3 */
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1)
-void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_tls( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
mbedtls_md5_context md5;
mbedtls_sha1_context sha1;
@@ -1276,10 +1866,12 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 );
mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 );
- mbedtls_md5_finish_ret( &md5, hash );
+ mbedtls_md5_finish_ret( &md5, hash );
mbedtls_sha1_finish_ret( &sha1, hash + 16 );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 );
+ *hlen = 36;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_md5_free( &md5 );
@@ -1291,8 +1883,34 @@ void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char *hash )
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
-void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
+void ssl_calc_verify_tls_sha256( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha256" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, hash, 32, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+
+ *hlen = 32;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha256_context sha256;
mbedtls_sha256_init( &sha256 );
@@ -1302,18 +1920,46 @@ void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 );
mbedtls_sha256_finish_ret( &sha256, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 );
+ *hlen = 32;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha256_free( &sha256 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
-void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+void ssl_calc_verify_tls_sha384( const mbedtls_ssl_context *ssl,
+ unsigned char *hash,
+ size_t *hlen )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_status_t status;
+ psa_hash_operation_t sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> PSA calc verify sha384" ) );
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, hash, 48, &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+
+ *hlen = 48;
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated verify result", hash, *hlen );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= PSA calc verify" ) );
+#else
mbedtls_sha512_context sha512;
mbedtls_sha512_init( &sha512 );
@@ -1323,29 +1969,35 @@ void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char *hash )
mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 );
mbedtls_sha512_finish_ret( &sha512, hash );
- MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 );
+ *hlen = 48;
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, *hlen );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) );
mbedtls_sha512_free( &sha512 );
-
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
return;
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex )
{
unsigned char *p = ssl->handshake->premaster;
unsigned char *end = p + sizeof( ssl->handshake->premaster );
- const unsigned char *psk = ssl->conf->psk;
- size_t psk_len = ssl->conf->psk_len;
+ const unsigned char *psk = NULL;
+ size_t psk_len = 0;
- /* If the psk callback was called, use its result */
- if( ssl->handshake->psk != NULL )
+ if( mbedtls_ssl_get_psk( ssl, &psk, &psk_len )
+ == MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED )
{
- psk = ssl->handshake->psk;
- psk_len = ssl->handshake->psk_len;
+ /*
+ * This should never happen because the existence of a PSK is always
+ * checked before calling this function
+ */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
/*
@@ -1361,8 +2013,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
+ MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+ p += 2;
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1391,7 +2043,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED)
if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Write length only when we know the actual value */
@@ -1402,9 +2054,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret );
return( ret );
}
- *(p++) = (unsigned char)( len >> 8 );
- *(p++) = (unsigned char)( len );
- p += len;
+ MBEDTLS_PUT_UINT16_BE( len, p, 0 );
+ p += 2 + len;
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
}
@@ -1413,7 +2064,7 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t zlen;
if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen,
@@ -1424,9 +2075,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
return( ret );
}
- *(p++) = (unsigned char)( zlen >> 8 );
- *(p++) = (unsigned char)( zlen );
- p += zlen;
+ MBEDTLS_PUT_UINT16_BE( zlen, p, 0 );
+ p += 2 + zlen;
MBEDTLS_SSL_DEBUG_ECDH( 3, &ssl->handshake->ecdh_ctx,
MBEDTLS_DEBUG_ECDH_Z );
@@ -1442,8 +2092,8 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- *(p++) = (unsigned char)( psk_len >> 8 );
- *(p++) = (unsigned char)( psk_len );
+ MBEDTLS_PUT_UINT16_BE( psk_len, p, 0 );
+ p += 2;
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -1455,1302 +2105,13 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
return( 0 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
-/*
- * SSLv3.0 MAC functions
- */
-#define SSL_MAC_MAX_BYTES 20 /* MD-5 or SHA-1 */
-static int ssl_mac( mbedtls_md_context_t *md_ctx,
- const unsigned char *secret,
- const unsigned char *buf, size_t len,
- const unsigned char *ctr, int type,
- unsigned char out[SSL_MAC_MAX_BYTES] )
-{
- unsigned char header[11];
- unsigned char padding[48];
- int padlen;
- int md_size = mbedtls_md_get_size( md_ctx->md_info );
- int md_type = mbedtls_md_get_type( md_ctx->md_info );
- int ret;
-
- /* Only MD5 and SHA-1 supported */
- if( md_type == MBEDTLS_MD_MD5 )
- padlen = 48;
- else
- padlen = 40;
-
- memcpy( header, ctr, 8 );
- header[ 8] = (unsigned char) type;
- header[ 9] = (unsigned char)( len >> 8 );
- header[10] = (unsigned char)( len );
-
- memset( padding, 0x36, padlen );
- ret = mbedtls_md_starts( md_ctx );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, secret, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, padding, padlen );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, header, 11 );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, buf, len );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_finish( md_ctx, out );
- if( ret != 0 )
- return( ret );
-
- memset( padding, 0x5C, padlen );
- ret = mbedtls_md_starts( md_ctx );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, secret, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, padding, padlen );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_update( md_ctx, out, md_size );
- if( ret != 0 )
- return( ret );
- ret = mbedtls_md_finish( md_ctx, out );
- if( ret != 0 )
- return( ret );
-
- return( 0 );
-}
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \
- defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
-#define SSL_SOME_MODES_USE_MAC
-#endif
-
-/*
- * Encryption/decryption functions
- */
-static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
-{
- mbedtls_cipher_mode_t mode;
- int auth_done = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) );
-
- if( ssl->session_out == NULL || ssl->transform_out == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- /*
- * Add MAC before if needed
- */
-#if defined(SSL_SOME_MODES_USE_MAC)
- if( mode == MBEDTLS_MODE_STREAM ||
- ( mode == MBEDTLS_MODE_CBC
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED
-#endif
- ) )
- {
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- unsigned char mac[SSL_MAC_MAX_BYTES];
- int ret;
-
- ret = ssl_mac( &ssl->transform_out->md_ctx_enc,
- ssl->transform_out->mac_enc,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_ctr, ssl->out_msgtype,
- mac );
-
- if( ret == 0 )
- memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
- return( ret );
- }
- }
- else
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- unsigned char mac[MBEDTLS_SSL_MAC_ADD];
- int ret;
-
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_msg, ssl->out_msglen );
- ret = mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- if( ret != 0 )
- goto hmac_failed_etm_disabled;
-
- memcpy( ssl->out_msg + ssl->out_msglen, mac, ssl->transform_out->maclen );
-
- hmac_failed_etm_disabled:
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_hmac_xxx", ret );
- return( ret );
- }
- }
- else
-#endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac",
- ssl->out_msg + ssl->out_msglen,
- ssl->transform_out->maclen );
-
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
- }
-#endif /* AEAD not the only option */
-
- /*
- * Encrypt
- */
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of padding",
- ssl->out_msglen, 0 ) );
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- ssl->out_msg, ssl->out_msglen,
- ssl->out_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( ssl->out_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
-#if defined(MBEDTLS_GCM_C) || \
- defined(MBEDTLS_CCM_C) || \
- defined(MBEDTLS_CHACHAPOLY_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM ||
- mode == MBEDTLS_MODE_CHACHAPOLY )
- {
- int ret;
- size_t enc_msglen, olen;
- unsigned char *enc_msg;
- unsigned char add_data[13];
- unsigned char iv[12];
- mbedtls_ssl_transform *transform = ssl->transform_out;
- unsigned char taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
-
- /*
- * Prepare additional authenticated data
- */
- memcpy( add_data, ssl->out_ctr, 8 );
- add_data[8] = ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->out_msglen & 0xFF;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
-
- /*
- * Generate IV
- */
- if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
- {
- /* GCM and CCM: fixed || explicit (=seqnum) */
- memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
- memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 );
- memcpy( ssl->out_iv, ssl->out_ctr, 8 );
-
- }
- else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
- {
- /* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
-
- memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
-
- for( i = 0; i < 8; i++ )
- iv[i+4] ^= ssl->out_ctr[i];
- }
- else
- {
- /* Reminder if we ever add an AEAD mode with a different size */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)",
- iv, transform->ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)",
- ssl->out_iv, explicit_ivlen );
-
- /*
- * Fix message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += explicit_ivlen;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including 0 bytes of padding",
- ssl->out_msglen ) );
-
- /*
- * Encrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
- iv, transform->ivlen,
- add_data, 13,
- enc_msg, enc_msglen,
- enc_msg, &olen,
- enc_msg + enc_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
- return( ret );
- }
-
- if( olen != enc_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->out_msglen += taglen;
- auth_done++;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
- }
- else
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
- if( mode == MBEDTLS_MODE_CBC )
- {
- int ret;
- unsigned char *enc_msg;
- size_t enc_msglen, padlen, olen = 0, i;
-
- padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) %
- ssl->transform_out->ivlen;
- if( padlen == ssl->transform_out->ivlen )
- padlen = 0;
-
- for( i = 0; i <= padlen; i++ )
- ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen;
-
- ssl->out_msglen += padlen + 1;
-
- enc_msglen = ssl->out_msglen;
- enc_msg = ssl->out_msg;
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Prepend per-record IV for block cipher in TLS v1.1 and up as per
- * Method 1 (6.2.3.2. in RFC4346 and RFC5246)
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Generate IV
- */
- ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
- if( ret != 0 )
- return( ret );
-
- memcpy( ssl->out_iv, ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen );
-
- /*
- * Fix pointer positions and message length with added IV
- */
- enc_msg = ssl->out_msg;
- enc_msglen = ssl->out_msglen;
- ssl->out_msglen += ssl->transform_out->ivlen;
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
- "including %d bytes of IV and %d bytes of padding",
- ssl->out_msglen, ssl->transform_out->ivlen,
- padlen + 1 ) );
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc,
- ssl->transform_out->iv_enc,
- ssl->transform_out->ivlen,
- enc_msg, enc_msglen,
- enc_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( enc_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_out->iv_enc,
- ssl->transform_out->cipher_ctx_enc.iv,
- ssl->transform_out->ivlen );
- }
-#endif
-
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( auth_done == 0 )
- {
- unsigned char mac[MBEDTLS_SSL_MAC_ADD];
-
- /*
- * MAC(MAC_write_key, seq_num +
- * TLSCipherText.type +
- * TLSCipherText.version +
- * length_of( (IV +) ENC(...) ) +
- * IV + // except for TLS 1.0
- * ENC(content + padding + padding_length));
- */
- unsigned char pseudo_hdr[13];
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
-
- memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
-
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc,
- ssl->out_iv, ssl->out_msglen );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, mac );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
-
- memcpy( ssl->out_iv + ssl->out_msglen, mac,
- ssl->transform_out->maclen );
-
- ssl->out_msglen += ssl->transform_out->maclen;
- auth_done++;
-
- hmac_failed_etm_enabled:
- mbedtls_platform_zeroize( mac, ssl->transform_out->maclen );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "HMAC calculation failed", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
- }
- else
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /* Make extra sure authentication was performed, exactly once */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
-
- 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 ) );
- }
-
- /* The context needs to finish() before it starts() again */
- MD_CHK( mbedtls_md_finish( ctx, aux_out ) );
-
- /* 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;
- int auth_done = 0;
-#if defined(SSL_SOME_MODES_USE_MAC)
- size_t padlen = 0, correct = 1;
-#endif
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) );
-
- if( ssl->session_in == NULL || ssl->transform_in == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec );
-
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)",
- ssl->in_msglen, ssl->transform_in->minlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
-#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
- if( mode == MBEDTLS_MODE_STREAM )
- {
- int ret;
- size_t olen = 0;
-
- padlen = 0;
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_msg, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( ssl->in_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */
-#if defined(MBEDTLS_GCM_C) || \
- defined(MBEDTLS_CCM_C) || \
- defined(MBEDTLS_CHACHAPOLY_C)
- if( mode == MBEDTLS_MODE_GCM ||
- mode == MBEDTLS_MODE_CCM ||
- mode == MBEDTLS_MODE_CHACHAPOLY )
- {
- int ret;
- size_t dec_msglen, olen;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- unsigned char add_data[13];
- unsigned char iv[12];
- mbedtls_ssl_transform *transform = ssl->transform_in;
- unsigned char taglen = transform->ciphersuite_info->flags &
- MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
- size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
-
- /*
- * Compute and update sizes
- */
- if( ssl->in_msglen < explicit_iv_len + taglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
- "+ taglen (%d)", ssl->in_msglen,
- explicit_iv_len, taglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
-
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
- ssl->in_msglen = dec_msglen;
-
- /*
- * Prepare additional authenticated data
- */
- memcpy( add_data, ssl->in_ctr, 8 );
- add_data[8] = ssl->in_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, add_data + 9 );
- add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF;
- add_data[12] = ssl->in_msglen & 0xFF;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 );
-
- /*
- * Prepare IV
- */
- if( transform->ivlen == 12 && transform->fixed_ivlen == 4 )
- {
- /* GCM and CCM: fixed || explicit (transmitted) */
- memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
- memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 );
-
- }
- else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
- {
- /* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
-
- memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
-
- for( i = 0; i < 8; i++ )
- iv[i+4] ^= ssl->in_ctr[i];
- }
- else
- {
- /* Reminder if we ever add an AEAD mode with a different size */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
-
- /*
- * Decrypt and authenticate
- */
- if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec,
- iv, transform->ivlen,
- add_data, 13,
- dec_msg, dec_msglen,
- dec_msg_result, &olen,
- dec_msg + dec_msglen, taglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
-
- if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
-
- return( ret );
- }
- auth_done++;
-
- if( olen != dec_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
- else
-#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
-#if defined(MBEDTLS_SSL_SOME_SUITES_USE_CBC)
- if( mode == MBEDTLS_MODE_CBC )
- {
- /*
- * Decrypt and check the padding
- */
- int ret;
- unsigned char *dec_msg;
- unsigned char *dec_msg_result;
- size_t dec_msglen;
- size_t minlen = 0;
- size_t olen = 0;
-
- /*
- * Check immediate ciphertext sanity
- */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- minlen += ssl->transform_in->ivlen;
-#endif
-
- if( ssl->in_msglen < minlen + ssl->transform_in->ivlen ||
- ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) "
- "+ 1 ) ( + expl IV )", ssl->in_msglen,
- ssl->transform_in->ivlen,
- ssl->transform_in->maclen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
- dec_msglen = ssl->in_msglen;
- dec_msg = ssl->in_msg;
- dec_msg_result = ssl->in_msg;
-
- /*
- * Authenticate before decrypt if enabled
- */
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED )
- {
- unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
- unsigned char pseudo_hdr[13];
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) );
-
- dec_msglen -= ssl->transform_in->maclen;
- ssl->in_msglen -= ssl->transform_in->maclen;
-
- memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 );
- memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 );
- pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF );
- pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 );
-
- ret = mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec,
- ssl->in_iv, ssl->in_msglen );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
- ret = mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec );
- if( ret != 0 )
- goto hmac_failed_etm_enabled;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen,
- ssl->transform_in->maclen );
- MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect,
- ssl->transform_in->maclen );
-
- if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, mac_expect,
- ssl->transform_in->maclen ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
-
- ret = MBEDTLS_ERR_SSL_INVALID_MAC;
- goto hmac_failed_etm_enabled;
- }
- auth_done++;
-
- hmac_failed_etm_enabled:
- mbedtls_platform_zeroize( mac_expect, ssl->transform_in->maclen );
- if( ret != 0 )
- {
- if( ret != MBEDTLS_ERR_SSL_INVALID_MAC )
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_hmac_xxx", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
-
- /*
- * Check length sanity
- */
- if( ssl->in_msglen % ssl->transform_in->ivlen != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0",
- ssl->in_msglen, ssl->transform_in->ivlen ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * Initialize for prepended IV for block cipher in TLS v1.1 and up
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- unsigned char i;
- dec_msglen -= ssl->transform_in->ivlen;
- ssl->in_msglen -= ssl->transform_in->ivlen;
-
- for( i = 0; i < ssl->transform_in->ivlen; i++ )
- ssl->transform_in->iv_dec[i] = ssl->in_iv[i];
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
-
- if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec,
- ssl->transform_in->iv_dec,
- ssl->transform_in->ivlen,
- dec_msg, dec_msglen,
- dec_msg_result, &olen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
- return( ret );
- }
-
- if( dec_msglen != olen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1)
- if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- /*
- * Save IV in SSL3 and TLS1
- */
- memcpy( ssl->transform_in->iv_dec,
- ssl->transform_in->cipher_ctx_dec.iv,
- ssl->transform_in->ivlen );
- }
-#endif
-
- padlen = 1 + ssl->in_msg[ssl->in_msglen - 1];
-
- if( ssl->in_msglen < ssl->transform_in->maclen + padlen &&
- auth_done == 0 )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)",
- ssl->in_msglen, ssl->transform_in->maclen, padlen ) );
-#endif
- padlen = 0;
- correct = 0;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( padlen > ssl->transform_in->ivlen )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, "
- "should be no more than %d",
- padlen, ssl->transform_in->ivlen ) );
-#endif
- correct = 0;
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /*
- * TLSv1+: always check the padding up to the first failure
- * and fake check up to 256 bytes of padding
- */
- size_t pad_count = 0, real_count = 1;
- size_t padding_idx = ssl->in_msglen - padlen;
- size_t i;
-
- /*
- * Padding is guaranteed to be incorrect if:
- * 1. padlen > ssl->in_msglen
- *
- * 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN +
- * ssl->transform_in->maclen
- *
- * In both cases we reset padding_idx to a safe value (0) to
- * prevent out-of-buffer reads.
- */
- correct &= ( padlen <= ssl->in_msglen );
- correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN +
- ssl->transform_in->maclen );
-
- padding_idx *= correct;
-
- for( i = 0; i < 256; i++ )
- {
- real_count &= ( i < padlen );
- pad_count += real_count *
- ( ssl->in_msg[padding_idx + i] == padlen - 1 );
- }
-
- correct &= ( pad_count == padlen ); /* Only 1 on correct padding */
-
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- if( padlen > 0 && correct == 0 )
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) );
-#endif
- padlen &= correct * 0x1FF;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_msglen -= padlen;
- }
- else
-#endif /* MBEDTLS_SSL_SOME_SUITES_USE_CBC) */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption",
- ssl->in_msg, ssl->in_msglen );
-#endif
-
- /*
- * Authenticate if not done yet.
- * Compute the MAC regardless of the padding result (RFC4346, CBCTIME).
- */
-#if defined(SSL_SOME_MODES_USE_MAC)
- if( auth_done == 0 )
- {
- unsigned char mac_expect[MBEDTLS_SSL_MAC_ADD];
- unsigned char mac_peer[MBEDTLS_SSL_MAC_ADD];
- int ret = 0;
-
- ssl->in_msglen -= ssl->transform_in->maclen;
-
- ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 );
- ssl->in_len[1] = (unsigned char)( ssl->in_msglen );
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- ret = ssl_mac( &ssl->transform_in->md_ctx_dec,
- ssl->transform_in->mac_dec,
- ssl->in_msg, ssl->in_msglen,
- ssl->in_ctr, ssl->in_msgtype,
- mac_expect );
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_mac", ret );
- return( ret );
- }
- memcpy( mac_peer, ssl->in_msg + ssl->in_msglen,
- ssl->transform_in->maclen );
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- unsigned char add_data[13];
-
- /*
- * The next two sizes are the minimum and maximum values of
- * in_msglen over all padlen values.
- *
- * They're independent of padlen, since we previously did
- * in_msglen -= padlen.
- *
- * Note that max_len + maclen is never more than the buffer
- * length, as we previously did in_msglen -= maclen too.
- */
- const size_t max_len = ssl->in_msglen + padlen;
- const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
-
- memcpy( add_data + 0, ssl->in_ctr, 8 );
- memcpy( add_data + 8, ssl->in_hdr, 3 );
- memcpy( add_data + 11, ssl->in_len, 2 );
-
- 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 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_cf_hmac", ret );
- goto hmac_failed_etm_disabled;
- }
-
- 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 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#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", mac_peer, ssl->transform_in->maclen );
-#endif
-
- if( mbedtls_ssl_safer_memcmp( mac_peer, mac_expect,
- ssl->transform_in->maclen ) != 0 )
- {
-#if defined(MBEDTLS_SSL_DEBUG_ALL)
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) );
-#endif
- correct = 0;
- }
- auth_done++;
-
- hmac_failed_etm_disabled:
- mbedtls_platform_zeroize( mac_peer, ssl->transform_in->maclen );
- mbedtls_platform_zeroize( mac_expect, ssl->transform_in->maclen );
- if( ret != 0 )
- return( ret );
- }
-
- /*
- * Finally check the correct flag
- */
- if( correct == 0 )
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
-#endif /* SSL_SOME_MODES_USE_MAC */
-
- /* Make extra sure authentication was performed, exactly once */
- if( auth_done != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- if( ssl->in_msglen == 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3
- && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- /* TLS v1.2 explicitly disallows zero-length messages which are not application data */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-
- ssl->nb_zero++;
-
- /*
- * Three or more empty messages may be a DoS attack
- * (excessive CPU consumption).
- */
- if( ssl->nb_zero > 3 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty "
- "messages, possible DoS attack" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
- }
- else
- ssl->nb_zero = 0;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ; /* in_ctr read from peer, not maintained internally */
- }
- else
-#endif
- {
- unsigned char i;
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->in_ctr[i - 1] != 0 )
- break;
-
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) );
-
- return( 0 );
-}
-
-#undef MAC_NONE
-#undef MAC_PLAINTEXT
-#undef MAC_CIPHERTEXT
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
-/*
- * Compression/decompression functions
- */
-static int ssl_compress_buf( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *msg_post = ssl->out_msg;
- ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
- size_t len_pre = ssl->out_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
-
- if( len_pre == 0 )
- return( 0 );
-
- memcpy( msg_pre, ssl->out_msg, len_pre );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ",
- ssl->out_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- ssl->transform_out->ctx_deflate.next_in = msg_pre;
- ssl->transform_out->ctx_deflate.avail_in = len_pre;
- ssl->transform_out->ctx_deflate.next_out = msg_post;
- ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written;
-
- ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
-
- ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN -
- ssl->transform_out->ctx_deflate.avail_out - bytes_written;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
- ssl->out_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload",
- ssl->out_msg, ssl->out_msglen );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) );
-
- return( 0 );
-}
-
-static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *msg_post = ssl->in_msg;
- ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
- size_t len_pre = ssl->in_msglen;
- unsigned char *msg_pre = ssl->compress_buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
-
- if( len_pre == 0 )
- return( 0 );
-
- memcpy( msg_pre, ssl->in_msg, len_pre );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ",
- ssl->in_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
-
- ssl->transform_in->ctx_inflate.next_in = msg_pre;
- ssl->transform_in->ctx_inflate.avail_in = len_pre;
- ssl->transform_in->ctx_inflate.next_out = msg_post;
- ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN -
- header_bytes;
-
- ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
- if( ret != Z_OK )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) );
- return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
- }
-
- ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN -
- ssl->transform_in->ctx_inflate.avail_out - header_bytes;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
- ssl->in_msglen ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload",
- ssl->in_msg, ssl->in_msglen );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) );
-
- return( 0 );
-}
-#endif /* MBEDTLS_ZLIB_SUPPORT */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
static int ssl_write_hello_request( mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_resend_hello_request( mbedtls_ssl_context *ssl )
{
/* If renegotiation is not enforced, retransmit until we would reach max
* timeout if we were using the usual handshake doubling scheme */
@@ -2777,2795 +2138,42 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
#endif
#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
-/*
- * Fill the input message buffer by appending data to it.
- * The amount of data already fetched is in ssl->in_left.
- *
- * If we return 0, is it guaranteed that (at least) nb_want bytes are
- * available (from this read and/or a previous one). Otherwise, an error code
- * is returned (possibly EOF or WANT_READ).
- *
- * With stream transport (TLS) on success ssl->in_left == nb_want, but
- * with datagram transport (DTLS) on success ssl->in_left >= nb_want,
- * since we always read a whole datagram at once.
- *
- * For DTLS, it is up to the caller to set ssl->next_record_offset when
- * they're done reading a record.
- */
-int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
-{
- int ret;
- size_t len;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
-
- if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- uint32_t timeout;
-
- /* Just to be sure */
- if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
- "mbedtls_ssl_set_timer_cb() for DTLS" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- /*
- * The point is, we need to always read a full datagram at once, so we
- * sometimes read more then requested, and handle the additional data.
- * It could be the rest of the current record (while fetching the
- * header) and/or some other records in the same datagram.
- */
-
- /*
- * Move to the next record in the already read datagram if applicable
- */
- if( ssl->next_record_offset != 0 )
- {
- if( ssl->in_left < ssl->next_record_offset )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_left -= ssl->next_record_offset;
-
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d",
- ssl->next_record_offset ) );
- memmove( ssl->in_hdr,
- ssl->in_hdr + ssl->next_record_offset,
- ssl->in_left );
- }
-
- ssl->next_record_offset = 0;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
-
- /*
- * Done if we already have enough data.
- */
- if( nb_want <= ssl->in_left)
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
- return( 0 );
- }
-
- /*
- * A record can't be split across datagrams. If we need to read but
- * are not at the beginning of a new record, the caller did something
- * wrong.
- */
- if( ssl->in_left != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Don't even try to read if time's out already.
- * This avoids by-passing the timer when repeatedly receiving messages
- * that will end up being dropped.
- */
- if( ssl_check_timer( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "timer has expired" ) );
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- }
- else
- {
- len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- timeout = ssl->handshake->retransmit_timeout;
- else
- timeout = ssl->conf->read_timeout;
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) );
-
- if( ssl->f_recv_timeout != NULL )
- ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len,
- timeout );
- else
- ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
-
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
- }
-
- if( ret == MBEDTLS_ERR_SSL_TIMEOUT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) );
- ssl_set_timer( ssl, 0 );
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- if( ssl_double_retransmit_timeout( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) );
- return( MBEDTLS_ERR_SSL_TIMEOUT );
- }
-
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
- }
-
- if( ret < 0 )
- return( ret );
-
- ssl->in_left = ret;
- }
- else
-#endif
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
-
- while( ssl->in_left < nb_want )
- {
- len = nb_want - ssl->in_left;
-
- if( ssl_check_timer( ssl ) != 0 )
- ret = MBEDTLS_ERR_SSL_TIMEOUT;
- else
- {
- if( ssl->f_recv_timeout != NULL )
- {
- ret = ssl->f_recv_timeout( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len,
- ssl->conf->read_timeout );
- }
- else
- {
- ret = ssl->f_recv( ssl->p_bio,
- ssl->in_hdr + ssl->in_left, len );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
- ssl->in_left, nb_want ) );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret );
-
- if( ret == 0 )
- return( MBEDTLS_ERR_SSL_CONN_EOF );
-
- if( ret < 0 )
- return( ret );
-
- 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",
- ret, (unsigned long)len ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->in_left += ret;
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
-
- return( 0 );
-}
-
-/*
- * Flush any data not yet written
- */
-int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
-{
- int ret;
- unsigned char *buf;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) );
-
- if( ssl->f_send == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() "
- "or mbedtls_ssl_set_bio()" ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- /* Avoid incrementing counter if data is flushed */
- if( ssl->out_left == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
- return( 0 );
- }
-
- while( ssl->out_left > 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d",
- mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) );
-
- buf = ssl->out_hdr - ssl->out_left;
- ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret );
-
- if( ret <= 0 )
- return( ret );
-
- 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",
- ret, (unsigned long)ssl->out_left ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- ssl->out_left -= ret;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- }
- else
-#endif
- {
- ssl->out_hdr = ssl->out_buf + 8;
- }
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
-
- return( 0 );
-}
-
-/*
- * Functions to handle the DTLS retransmission state machine
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-/*
- * Append current handshake message to current outgoing flight
- */
-static int ssl_flight_append( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_flight_item *msg;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_flight_append" ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "message appended to flight",
- ssl->out_msg, ssl->out_msglen );
-
- /* Allocate space for current message */
- if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed",
- sizeof( mbedtls_ssl_flight_item ) ) );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) );
- mbedtls_free( msg );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- /* Copy current handshake message with headers */
- memcpy( msg->p, ssl->out_msg, ssl->out_msglen );
- msg->len = ssl->out_msglen;
- msg->type = ssl->out_msgtype;
- msg->next = NULL;
-
- /* Append to the current flight */
- if( ssl->handshake->flight == NULL )
- ssl->handshake->flight = msg;
- else
- {
- mbedtls_ssl_flight_item *cur = ssl->handshake->flight;
- while( cur->next != NULL )
- cur = cur->next;
- cur->next = msg;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
- return( 0 );
-}
-
-/*
- * Free the current flight of handshake messages
- */
-static void ssl_flight_free( mbedtls_ssl_flight_item *flight )
-{
- mbedtls_ssl_flight_item *cur = flight;
- mbedtls_ssl_flight_item *next;
-
- while( cur != NULL )
- {
- next = cur->next;
-
- mbedtls_free( cur->p );
- mbedtls_free( cur );
-
- cur = next;
- }
-}
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
-#endif
-
-/*
- * Swap transform_out and out_ctr with the alternative ones
- */
-static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_transform *tmp_transform;
- unsigned char tmp_out_ctr[8];
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- int ret;
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
-
- if( ssl->transform_out == ssl->handshake->alt_transform_out )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
- return( 0 );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
-
- /* Swap transforms */
- tmp_transform = ssl->transform_out;
- ssl->transform_out = ssl->handshake->alt_transform_out;
- ssl->handshake->alt_transform_out = tmp_transform;
-
- /* Swap epoch + sequence_number */
- memcpy( tmp_out_ctr, ssl->cur_out_ctr, 8 );
- memcpy( ssl->cur_out_ctr, ssl->handshake->alt_out_ctr, 8 );
- memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 );
-
- /* Adjust to the newly activated transform */
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
- {
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
-
- return( 0 );
-}
-
-/*
- * Retransmit the current flight of messages.
- */
-int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
-{
- int ret = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) );
-
- ret = mbedtls_ssl_flight_transmit( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) );
-
- return( ret );
-}
-
-/*
- * Transmit or retransmit the current flight of messages.
- *
- * Need to remember the current message in case flush_output returns
- * WANT_WRITE, causing us to exit this function and come back later.
- * This function must be called until state is no longer SENDING.
- */
-int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
-{
- int ret;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_flight_transmit" ) );
-
- if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise flight transmission" ) );
-
- ssl->handshake->cur_msg = ssl->handshake->flight;
- ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
-
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
- }
-
- while( ssl->handshake->cur_msg != NULL )
- {
- size_t max_frag_len;
- const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
-
- int const is_finished =
- ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
- cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
-
- uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
- SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
-
- /* Swap epochs before sending Finished: we can't do it after
- * sending ChangeCipherSpec, in case write returns WANT_READ.
- * Must be done before copying, may change out_msg pointer */
- if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- ret = ssl_get_remaining_payload_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
- max_frag_len = (size_t) ret;
-
- /* CCS is copied as is, while HS messages may need fragmentation */
- if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- if( max_frag_len == 0 )
- {
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
-
- memcpy( ssl->out_msg, cur->p, cur->len );
- ssl->out_msglen = cur->len;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur->len;
- }
- else
- {
- const unsigned char * const p = ssl->handshake->cur_msg_p;
- const size_t hs_len = cur->len - 12;
- const size_t frag_off = p - ( cur->p + 12 );
- const size_t rem_len = hs_len - frag_off;
- size_t cur_hs_frag_len, max_hs_frag_len;
-
- if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
- {
- if( is_finished )
- {
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
- max_hs_frag_len = max_frag_len - 12;
-
- cur_hs_frag_len = rem_len > max_hs_frag_len ?
- max_hs_frag_len : rem_len;
-
- if( frag_off == 0 && cur_hs_frag_len != hs_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
- (unsigned) cur_hs_frag_len,
- (unsigned) max_hs_frag_len ) );
- }
-
- /* Messages are stored with handshake headers as if not fragmented,
- * copy beginning of headers then fill fragmentation fields.
- * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
- memcpy( ssl->out_msg, cur->p, 6 );
-
- ssl->out_msg[6] = ( ( frag_off >> 16 ) & 0xff );
- ssl->out_msg[7] = ( ( frag_off >> 8 ) & 0xff );
- ssl->out_msg[8] = ( ( frag_off ) & 0xff );
-
- ssl->out_msg[ 9] = ( ( cur_hs_frag_len >> 16 ) & 0xff );
- ssl->out_msg[10] = ( ( cur_hs_frag_len >> 8 ) & 0xff );
- ssl->out_msg[11] = ( ( cur_hs_frag_len ) & 0xff );
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
-
- /* Copy the handshake message content and set records fields */
- memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
- ssl->out_msglen = cur_hs_frag_len + 12;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur_hs_frag_len;
- }
-
- /* If done with the current message move to the next one if any */
- if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
- {
- if( cur->next != NULL )
- {
- ssl->handshake->cur_msg = cur->next;
- ssl->handshake->cur_msg_p = cur->next->p + 12;
- }
- else
- {
- ssl->handshake->cur_msg = NULL;
- ssl->handshake->cur_msg_p = NULL;
- }
- }
-
- /* Actually send the message out */
- if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
- }
- }
-
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- /* Update state and set timer */
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- else
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
-
- return( 0 );
-}
-
-/*
- * To be called when the last message of an incoming flight is received.
- */
-void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl )
-{
- /* We won't need to resend that one any more */
- ssl_flight_free( ssl->handshake->flight );
- ssl->handshake->flight = NULL;
- ssl->handshake->cur_msg = NULL;
-
- /* The next incoming flight will start with this msg_seq */
- ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq;
-
- /* We don't want to remember CCS's across flight boundaries. */
- ssl->handshake->buffering.seen_ccs = 0;
-
- /* Clear future message buffering structure. */
- ssl_buffering_free( ssl );
-
- /* Cancel timer */
- ssl_set_timer( ssl, 0 );
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING;
-}
-
-/*
- * To be called when the last message of an outgoing flight is send.
- */
-void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
-{
- ssl_reset_retransmit_timeout( ssl );
- ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED )
- {
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
- }
- else
- ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
-}
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-/*
- * Handshake layer functions
- */
-
-/*
- * Write (DTLS: or queue) current handshake (including CCS) message.
- *
- * - fill in handshake headers
- * - update handshake checksum
- * - DTLS: save message for resending
- * - then pass to the record layer
- *
- * DTLS: except for HelloRequest, messages are only queued, and will only be
- * actually sent when calling flight_transmit() or resend().
- *
- * Inputs:
- * - ssl->out_msglen: 4 + actual handshake message len
- * (4 is the size of handshake headers for TLS)
- * - ssl->out_msg[0]: the handshake type (ClientHello, ServerHello, etc)
- * - ssl->out_msg + 4: the handshake message body
- *
- * Outputs, ie state before passing to flight_append() or write_record():
- * - ssl->out_msglen: the length of the record contents
- * (including handshake headers but excluding record headers)
- * - ssl->out_msg: the record contents (handshake headers + content)
- */
-int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
-{
- int ret;
- const size_t hs_len = ssl->out_msglen - 4;
- const unsigned char hs_type = ssl->out_msg[0];
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write handshake message" ) );
-
- /*
- * Sanity checks
- */
- if( ssl->out_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->out_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- /* In SSLv3, the client might send a NoCertificate alert. */
-#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C)
- if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) )
-#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
-
- /* Whenever we send anything different from a
- * HelloRequest we should be in a handshake - double check. */
- if( ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) &&
- ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-#endif
-
- /* Double-check that we did not exceed the bounds
- * of the outgoing record buffer.
- * This should never fail as the various message
- * writing functions must obey the bounds of the
- * outgoing record buffer, but better be safe.
- *
- * Note: We deliberately do not check for the MTU or MFL here.
- */
- if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record too large: "
- "size %u, maximum %u",
- (unsigned) ssl->out_msglen,
- (unsigned) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Fill handshake headers
- */
- if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- ssl->out_msg[1] = (unsigned char)( hs_len >> 16 );
- ssl->out_msg[2] = (unsigned char)( hs_len >> 8 );
- ssl->out_msg[3] = (unsigned char)( hs_len );
-
- /*
- * DTLS has additional fields in the Handshake layer,
- * between the length field and the actual payload:
- * uint16 message_seq;
- * uint24 fragment_offset;
- * uint24 fragment_length;
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Make room for the additional DTLS fields */
- if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: "
- "size %u, maximum %u",
- (unsigned) ( hs_len ),
- (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
-
- memmove( ssl->out_msg + 12, ssl->out_msg + 4, hs_len );
- ssl->out_msglen += 8;
-
- /* Write message_seq and update it, except for HelloRequest */
- if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
- {
- ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
- ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
- ++( ssl->handshake->out_msg_seq );
- }
- else
- {
- ssl->out_msg[4] = 0;
- ssl->out_msg[5] = 0;
- }
-
- /* Handshake hashes are computed without fragmentation,
- * so set frag_offset = 0 and frag_len = hs_len for now */
- memset( ssl->out_msg + 6, 0x00, 3 );
- memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- /* Update running hashes of handshake messages seen */
- if( hs_type != MBEDTLS_SSL_HS_HELLO_REQUEST )
- ssl->handshake->update_checksum( ssl, ssl->out_msg, ssl->out_msglen );
- }
-
- /* Either send now, or just save to be sent (and resent) later */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
- {
- if( ( ret = ssl_flight_append( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret );
- return( ret );
- }
- }
- else
-#endif
- {
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_write_record", ret );
- return( ret );
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write handshake message" ) );
-
- return( 0 );
-}
-
-/*
- * Record layer functions
- */
-
-/*
- * Write current record.
- *
- * Uses:
- * - ssl->out_msgtype: type of the message (AppData, Handshake, Alert, CCS)
- * - ssl->out_msglen: length of the record content (excl headers)
- * - ssl->out_msg: record content
- */
-int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
-{
- int ret, done = 0;
- size_t len = ssl->out_msglen;
- uint8_t flush = force_flush;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_out != NULL &&
- ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_compress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret );
- return( ret );
- }
-
- len = ssl->out_msglen;
- }
-#endif /*MBEDTLS_ZLIB_SUPPORT */
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_write != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) );
-
- ret = mbedtls_ssl_hw_record_write( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
-
- if( ret == 0 )
- done = 1;
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done )
- {
- unsigned i;
- size_t protected_record_size;
-
- ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype;
- mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver,
- ssl->conf->transport, ssl->out_hdr + 1 );
-
- memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
-
- if( ssl->transform_out != NULL )
- {
- if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret );
- return( ret );
- }
-
- len = ssl->out_msglen;
- ssl->out_len[0] = (unsigned char)( len >> 8 );
- ssl->out_len[1] = (unsigned char)( len );
- }
-
- protected_record_size = len + mbedtls_ssl_hdr_len( ssl );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* In case of DTLS, double-check that we don't exceed
- * the remaining space in the datagram. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ret = ssl_get_remaining_space_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
-
- if( protected_record_size > (size_t) ret )
- {
- /* Should never happen */
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->out_hdr[0], ssl->out_hdr[1],
- ssl->out_hdr[2], len ) );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_hdr, protected_record_size );
-
- ssl->out_left += protected_record_size;
- ssl->out_hdr += protected_record_size;
- ssl_update_out_pointers( ssl, ssl->transform_out );
-
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
- if( ++ssl->cur_out_ctr[i - 1] != 0 )
- break;
-
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) );
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- flush == SSL_DONT_FORCE_FLUSH )
- {
- size_t remaining;
- ret = ssl_get_remaining_payload_in_datagram( ssl );
- if( ret < 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_remaining_payload_in_datagram",
- ret );
- return( ret );
- }
-
- remaining = (size_t) ret;
- if( remaining == 0 )
- {
- flush = SSL_FORCE_FLUSH;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Still %u bytes available in current datagram", (unsigned) remaining ) );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- if( ( flush == SSL_FORCE_FLUSH ) &&
- ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-static int ssl_hs_is_proper_fragment( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen < ssl->in_hslen ||
- memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 ||
- memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 )
- {
- return( 1 );
- }
- return( 0 );
-}
-
-static uint32_t ssl_get_hs_frag_len( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[9] << 16 ) |
- ( ssl->in_msg[10] << 8 ) |
- ssl->in_msg[11] );
-}
-
-static uint32_t ssl_get_hs_frag_off( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[6] << 16 ) |
- ( ssl->in_msg[7] << 8 ) |
- ssl->in_msg[8] );
-}
-
-static int ssl_check_hs_header( mbedtls_ssl_context const *ssl )
-{
- uint32_t msg_len, frag_off, frag_len;
-
- msg_len = ssl_get_hs_total_len( ssl );
- frag_off = ssl_get_hs_frag_off( ssl );
- frag_len = ssl_get_hs_frag_len( ssl );
-
- if( frag_off > msg_len )
- return( -1 );
-
- if( frag_len > msg_len - frag_off )
- return( -1 );
-
- if( frag_len + 12 > ssl->in_msglen )
- return( -1 );
-
- return( 0 );
-}
-
-/*
- * Mark bits in bitmask (used for DTLS HS reassembly)
- */
-static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len )
-{
- unsigned int start_bits, end_bits;
-
- start_bits = 8 - ( offset % 8 );
- if( start_bits != 8 )
- {
- size_t first_byte_idx = offset / 8;
-
- /* Special case */
- if( len <= start_bits )
- {
- for( ; len != 0; len-- )
- mask[first_byte_idx] |= 1 << ( start_bits - len );
-
- /* Avoid potential issues with offset or len becoming invalid */
- return;
- }
-
- offset += start_bits; /* Now offset % 8 == 0 */
- len -= start_bits;
-
- for( ; start_bits != 0; start_bits-- )
- mask[first_byte_idx] |= 1 << ( start_bits - 1 );
- }
-
- end_bits = len % 8;
- if( end_bits != 0 )
- {
- size_t last_byte_idx = ( offset + len ) / 8;
-
- len -= end_bits; /* Now len % 8 == 0 */
-
- for( ; end_bits != 0; end_bits-- )
- mask[last_byte_idx] |= 1 << ( 8 - end_bits );
- }
-
- memset( mask + offset / 8, 0xFF, len / 8 );
-}
-
-/*
- * Check that bitmask is full
- */
-static int ssl_bitmask_check( unsigned char *mask, size_t len )
-{
- size_t i;
-
- for( i = 0; i < len / 8; i++ )
- if( mask[i] != 0xFF )
- return( -1 );
-
- for( i = 0; i < len % 8; i++ )
- if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 )
- return( -1 );
-
- return( 0 );
-}
-
-/* msg_len does not include the handshake header */
-static size_t ssl_get_reassembly_buffer_size( size_t msg_len,
- unsigned add_bitmap )
-{
- size_t alloc_len;
-
- alloc_len = 12; /* Handshake header */
- alloc_len += msg_len; /* Content buffer */
-
- if( add_bitmap )
- alloc_len += msg_len / 8 + ( msg_len % 8 != 0 ); /* Bitmap */
-
- return( alloc_len );
-}
-
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static uint32_t ssl_get_hs_total_len( mbedtls_ssl_context const *ssl )
-{
- return( ( ssl->in_msg[1] << 16 ) |
- ( ssl->in_msg[2] << 8 ) |
- ssl->in_msg[3] );
-}
-
-int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ssl_get_hs_total_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen ="
- " %d, type = %d, hslen = %d",
- ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- int ret;
- unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
-
- if( ssl_check_hs_header( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid handshake header" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( ssl->handshake != NULL &&
- ( ( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
- recv_msg_seq != ssl->handshake->in_msg_seq ) ||
- ( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) ) )
- {
- if( recv_msg_seq > ssl->handshake->in_msg_seq )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received future handshake message of sequence number %u (next %u)",
- recv_msg_seq,
- ssl->handshake->in_msg_seq ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-
- /* Retransmit only on last message from previous flight, to avoid
- * too many retransmissions.
- * Besides, No sane server ever retransmits HelloVerifyRequest */
- if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, "
- "message_seq = %d, start_of_flight = %d",
- recv_msg_seq,
- ssl->handshake->in_flight_start_seq ) );
-
- if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret );
- return( ret );
- }
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: "
- "message_seq = %d, expected = %d",
- recv_msg_seq,
- ssl->handshake->in_msg_seq ) );
- }
-
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
- /* Wait until message completion to increment in_msg_seq */
-
- /* Message reassembly is handled alongside buffering of future
- * messages; the commonality is that both handshake fragments and
- * future messages cannot be forwarded immediately to the
- * handshake logic layer. */
- if( ssl_hs_is_proper_fragment( ssl ) == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- /* With TLS we don't handle fragmentation (for now) */
- if( ssl->in_msglen < ssl->in_hslen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
- }
-
- return( 0 );
-}
-
-void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && hs != NULL )
- {
- ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen );
- }
-
- /* Handshake message is complete, increment counter */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL )
- {
- unsigned offset;
- mbedtls_ssl_hs_buffer *hs_buf;
-
- /* Increment handshake sequence number */
- hs->in_msg_seq++;
-
- /*
- * Clear up handshake buffering and reassembly structure.
- */
-
- /* Free first entry */
- ssl_buffering_free_slot( ssl, 0 );
-
- /* Shift all other entries */
- for( offset = 0, hs_buf = &hs->buffering.hs[0];
- offset + 1 < MBEDTLS_SSL_MAX_BUFFERED_HS;
- offset++, hs_buf++ )
- {
- *hs_buf = *(hs_buf + 1);
- }
-
- /* Create a fresh last entry */
- memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
- }
-#endif
-}
-
-/*
- * DTLS anti-replay: RFC 6347 4.1.2.6
- *
- * in_window is a field of bits numbered from 0 (lsb) to 63 (msb).
- * Bit n is set iff record number in_window_top - n has been seen.
- *
- * Usually, in_window_top is the last record number seen and the lsb of
- * in_window is set. The only exception is the initial state (record number 0
- * not seen yet).
- */
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl )
-{
- ssl->in_window_top = 0;
- ssl->in_window = 0;
-}
-
-static inline uint64_t ssl_load_six_bytes( unsigned char *buf )
-{
- return( ( (uint64_t) buf[0] << 40 ) |
- ( (uint64_t) buf[1] << 32 ) |
- ( (uint64_t) buf[2] << 24 ) |
- ( (uint64_t) buf[3] << 16 ) |
- ( (uint64_t) buf[4] << 8 ) |
- ( (uint64_t) buf[5] ) );
-}
-
-/*
- * Return 0 if sequence number is acceptable, -1 otherwise
- */
-int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl )
-{
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
- uint64_t bit;
-
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return( 0 );
-
- if( rec_seqnum > ssl->in_window_top )
- return( 0 );
-
- bit = ssl->in_window_top - rec_seqnum;
-
- if( bit >= 64 )
- return( -1 );
-
- if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 )
- return( -1 );
-
- return( 0 );
-}
-
-/*
- * Update replay window on new validated record
- */
-void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl )
-{
- uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 );
-
- if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED )
- return;
-
- if( rec_seqnum > ssl->in_window_top )
- {
- /* Update window_top and the contents of the window */
- uint64_t shift = rec_seqnum - ssl->in_window_top;
-
- if( shift >= 64 )
- ssl->in_window = 1;
- else
- {
- ssl->in_window <<= shift;
- ssl->in_window |= 1;
- }
-
- ssl->in_window_top = rec_seqnum;
- }
- else
- {
- /* Mark that number as seen in the current window */
- uint64_t bit = ssl->in_window_top - rec_seqnum;
-
- if( bit < 64 ) /* Always true, but be extra sure */
- ssl->in_window |= (uint64_t) 1 << bit;
- }
-}
-#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
-/* Forward declaration */
-static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial );
-
-/*
- * Without any SSL context, check if a datagram looks like a ClientHello with
- * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message.
- * Both input and output include full DTLS headers.
- *
- * - if cookie is valid, return 0
- * - if ClientHello looks superficially valid but cookie is not,
- * fill obuf and set olen, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - otherwise return a specific error code
- */
-static int ssl_check_dtls_clihlo_cookie(
- mbedtls_ssl_cookie_write_t *f_cookie_write,
- mbedtls_ssl_cookie_check_t *f_cookie_check,
- void *p_cookie,
- const unsigned char *cli_id, size_t cli_id_len,
- const unsigned char *in, size_t in_len,
- unsigned char *obuf, size_t buf_len, size_t *olen )
-{
- size_t sid_len, cookie_len;
- unsigned char *p;
-
- if( f_cookie_write == NULL || f_cookie_check == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- /*
- * Structure of ClientHello with record and handshake headers,
- * and expected values. We don't need to check a lot, more checks will be
- * done when actually parsing the ClientHello - skipping those checks
- * avoids code duplication and does not make cookie forging any easier.
- *
- * 0-0 ContentType type; copied, must be handshake
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied, must be 0
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; (ignored)
- *
- * 13-13 HandshakeType msg_type; (ignored)
- * 14-16 uint24 length; (ignored)
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied, must be 0
- * 22-24 uint24 fragment_length; (ignored)
- *
- * 25-26 ProtocolVersion client_version; (ignored)
- * 27-58 Random random; (ignored)
- * 59-xx SessionID session_id; 1 byte len + sid_len content
- * 60+ opaque cookie<0..2^8-1>; 1 byte len + content
- * ...
- *
- * Minimum length is 61 bytes.
- */
- if( in_len < 61 ||
- in[0] != MBEDTLS_SSL_MSG_HANDSHAKE ||
- in[3] != 0 || in[4] != 0 ||
- in[19] != 0 || in[20] != 0 || in[21] != 0 )
- {
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
- }
-
- sid_len = in[59];
- if( sid_len > in_len - 61 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-
- cookie_len = in[60 + sid_len];
- if( cookie_len > in_len - 60 )
- return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
-
- if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len,
- cli_id, cli_id_len ) == 0 )
- {
- /* Valid cookie */
- return( 0 );
- }
-
- /*
- * If we get here, we've got an invalid cookie, let's prepare HVR.
- *
- * 0-0 ContentType type; copied
- * 1-2 ProtocolVersion version; copied
- * 3-4 uint16 epoch; copied
- * 5-10 uint48 sequence_number; copied
- * 11-12 uint16 length; olen - 13
- *
- * 13-13 HandshakeType msg_type; hello_verify_request
- * 14-16 uint24 length; olen - 25
- * 17-18 uint16 message_seq; copied
- * 19-21 uint24 fragment_offset; copied
- * 22-24 uint24 fragment_length; olen - 25
- *
- * 25-26 ProtocolVersion server_version; 0xfe 0xff
- * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie
- *
- * Minimum length is 28.
- */
- if( buf_len < 28 )
- return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
-
- /* Copy most fields and adapt others */
- memcpy( obuf, in, 25 );
- obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST;
- obuf[25] = 0xfe;
- obuf[26] = 0xff;
-
- /* Generate and write actual cookie */
- p = obuf + 28;
- if( f_cookie_write( p_cookie,
- &p, obuf + buf_len, cli_id, cli_id_len ) != 0 )
- {
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- *olen = p - obuf;
-
- /* Go back and fill length fields */
- obuf[27] = (unsigned char)( *olen - 28 );
-
- obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 );
- obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 );
- obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) );
-
- obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 );
- obuf[12] = (unsigned char)( ( *olen - 13 ) );
-
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
-}
-
-/*
- * Handle possible client reconnect with the same UDP quadruplet
- * (RFC 6347 Section 4.2.8).
- *
- * Called by ssl_parse_record_header() in case we receive an epoch 0 record
- * that looks like a ClientHello.
- *
- * - if the input looks like a ClientHello without cookies,
- * send back HelloVerifyRequest, then
- * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED
- * - if the input looks like a ClientHello with a valid cookie,
- * reset the session of the current context, and
- * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
- * - if anything goes wrong, return a specific error code
- *
- * mbedtls_ssl_read_record() will ignore the record if anything else than
- * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function
- * cannot not return 0.
- */
-static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
-{
- int ret;
- size_t len;
-
- ret = ssl_check_dtls_clihlo_cookie(
- ssl->conf->f_cookie_write,
- ssl->conf->f_cookie_check,
- ssl->conf->p_cookie,
- ssl->cli_id, ssl->cli_id_len,
- ssl->in_buf, ssl->in_left,
- ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len );
-
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret );
-
- if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
- {
- int send_ret;
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
- MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
- ssl->out_buf, len );
- /* Don't check write errors as we can't do anything here.
- * If the error is permanent we'll catch it later,
- * if it's not, then hopefully it'll work next time. */
- send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
- MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
- (void) send_ret;
-
- return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
- }
-
- if( ret == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
- if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
- return( ret );
- }
-
- return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT );
- }
-
- return( ret );
-}
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
-
-/*
- * ContentType type;
- * ProtocolVersion version;
- * uint16 epoch; // DTLS only
- * uint48 sequence_number; // DTLS only
- * uint16 length;
- *
- * Return 0 if header looks sane (and, for DTLS, the record is expected)
- * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
- * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
- *
- * With DTLS, mbedtls_ssl_read_record() will:
- * 1. proceed with the record if this function returns 0
- * 2. drop only the current record if this function returns UNEXPECTED_RECORD
- * 3. return CLIENT_RECONNECT if this function return that value
- * 4. drop the whole datagram if this function returns anything else.
- * Point 2 is needed when the peer is resending, and we have already received
- * the first record from a datagram but are still waiting for the others.
- */
-static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
-{
- int major_ver, minor_ver;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) );
-
- ssl->in_msgtype = ssl->in_hdr[0];
- ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1];
- mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 );
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, "
- "version = [%d:%d], msglen = %d",
- ssl->in_msgtype,
- major_ver, minor_ver, ssl->in_msglen ) );
-
- /* Check record type */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
- ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* Silently ignore invalid DTLS records as recommended by RFC 6347
- * Section 4.1.2.7 */
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
-
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /* Check version */
- if( major_ver != ssl->major_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( minor_ver > ssl->conf->max_minor_ver )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /* Check length against the size of our buffer */
- if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN
- - (size_t)( ssl->in_msg - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- /*
- * DTLS-related tests.
- * Check epoch before checking length constraint because
- * the latter varies with the epoch. E.g., if a ChangeCipherSpec
- * message gets duplicated before the corresponding Finished message,
- * the second ChangeCipherSpec should be discarded because it belongs
- * to an old epoch, but not because its length is shorter than
- * the minimum record length for packets using the new record transform.
- * Note that these two kinds of failures are handled differently,
- * as an unexpected record is silently skipped but an invalid
- * record leads to the entire datagram being dropped.
- */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
-
- /* Check epoch (and sequence number) with DTLS */
- if( rec_epoch != ssl->in_epoch )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
- "expected %d, received %d",
- ssl->in_epoch, rec_epoch ) );
-
-#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
- /*
- * Check for an epoch 0 ClientHello. We can't use in_msg here to
- * access the first byte of record content (handshake type), as we
- * have an active transform (possibly iv_len != 0), so use the
- * fact that the record header len is 13 instead.
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
- rec_epoch == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_left > 13 &&
- ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
- "from the same port" ) );
- return( ssl_handle_possible_reconnect( ssl ) );
- }
- else
-#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
- {
- /* Consider buffering the record. */
- if( rec_epoch == (unsigned int) ssl->in_epoch + 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Consider record for buffering" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- }
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- /* Replay detection only works for the current epoch */
- if( rec_epoch == ssl->in_epoch &&
- mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
-#endif
-
- /* Drop unexpected ApplicationData records,
- * except at the beginning of renegotiations */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
- ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
- ssl->state == MBEDTLS_SSL_SERVER_HELLO )
-#endif
- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-
- /* Check length against bounds of the current transform and version */
- if( ssl->transform_in == NULL )
- {
- if( ssl->in_msglen < 1 ||
- ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
- else
- {
- if( ssl->in_msglen < ssl->transform_in->minlen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- /*
- * TLS encrypted messages can have up to 256 bytes of padding
- */
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 &&
- ssl->in_msglen > ssl->transform_in->minlen +
- MBEDTLS_SSL_IN_CONTENT_LEN + 256 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-#endif
- }
-
- return( 0 );
-}
-
-/*
- * If applicable, decrypt (and decompress) record content
- */
-static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
-{
- int ret, done = 0;
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network",
- ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen );
-
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_read != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) );
-
- ret = mbedtls_ssl_hw_record_read( ssl );
- if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
-
- if( ret == 0 )
- done = 1;
- }
-#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
- if( !done && ssl->transform_in != NULL )
- {
- if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret );
- return( ret );
- }
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt",
- ssl->in_msg, ssl->in_msglen );
-
- if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
- }
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->transform_in != NULL &&
- ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE )
- {
- if( ( ret = ssl_decompress_buf( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_ZLIB_SUPPORT */
-
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- mbedtls_ssl_dtls_replay_update( ssl );
- }
-#endif
-
- return( 0 );
-}
-
-static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
-
-/*
- * Read a record.
- *
- * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
- * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
- *
- */
-
-/* Helper functions for mbedtls_ssl_read_record(). */
-static int ssl_consume_current_message( mbedtls_ssl_context *ssl );
-static int ssl_get_next_record( mbedtls_ssl_context *ssl );
-static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl );
-
-int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl,
- unsigned update_hs_digest )
-{
- int ret;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
-
- if( ssl->keep_current_message == 0 )
- {
- do {
-
- ret = ssl_consume_current_message( ssl );
- if( ret != 0 )
- return( ret );
-
- if( ssl_record_is_in_progress( ssl ) == 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- int have_buffered = 0;
-
- /* We only check for buffered messages if the
- * current datagram is fully consumed. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl_next_record_is_in_datagram( ssl ) == 0 )
- {
- if( ssl_load_buffered_message( ssl ) == 0 )
- have_buffered = 1;
- }
-
- if( have_buffered == 0 )
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- {
- ret = ssl_get_next_record( ssl );
- if( ret == MBEDTLS_ERR_SSL_CONTINUE_PROCESSING )
- continue;
-
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_get_next_record" ), ret );
- return( ret );
- }
- }
- }
-
- ret = mbedtls_ssl_handle_message_type( ssl );
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
- {
- /* Buffer future message */
- ret = ssl_buffer_message( ssl );
- if( ret != 0 )
- return( ret );
-
- ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING;
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ||
- MBEDTLS_ERR_SSL_CONTINUE_PROCESSING == ret );
-
- if( 0 != ret )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret );
- return( ret );
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- update_hs_digest == 1 )
- {
- mbedtls_ssl_update_handshake_status( ssl );
- }
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "reuse previously read message" ) );
- ssl->keep_current_message = 0;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static int ssl_next_record_is_in_datagram( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_left > ssl->next_record_offset )
- return( 1 );
-
- return( 0 );
-}
-
-static int ssl_load_buffered_message( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- mbedtls_ssl_hs_buffer * hs_buf;
- int ret = 0;
-
- if( hs == NULL )
- return( -1 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_messsage" ) );
-
- if( ssl->state == MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC ||
- ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
- {
- /* Check if we have seen a ChangeCipherSpec before.
- * If yes, synthesize a CCS record. */
- if( !hs->buffering.seen_ccs )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "CCS not seen in the current flight" ) );
- ret = -1;
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Injecting buffered CCS message" ) );
- ssl->in_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
- ssl->in_msglen = 1;
- ssl->in_msg[0] = 1;
-
- /* As long as they are equal, the exact value doesn't matter. */
- ssl->in_left = 0;
- ssl->next_record_offset = 0;
-
- hs->buffering.seen_ccs = 0;
- goto exit;
- }
-
-#if defined(MBEDTLS_DEBUG_C)
- /* Debug only */
- {
- unsigned offset;
- for( offset = 1; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
- {
- hs_buf = &hs->buffering.hs[offset];
- if( hs_buf->is_valid == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Future message with sequence number %u %s buffered.",
- hs->in_msg_seq + offset,
- hs_buf->is_complete ? "fully" : "partially" ) );
- }
- }
- }
-#endif /* MBEDTLS_DEBUG_C */
-
- /* Check if we have buffered and/or fully reassembled the
- * next handshake message. */
- hs_buf = &hs->buffering.hs[0];
- if( ( hs_buf->is_valid == 1 ) && ( hs_buf->is_complete == 1 ) )
- {
- /* Synthesize a record containing the buffered HS message. */
- size_t msg_len = ( hs_buf->data[1] << 16 ) |
- ( hs_buf->data[2] << 8 ) |
- hs_buf->data[3];
-
- /* Double-check that we haven't accidentally buffered
- * a message that doesn't fit into the input buffer. */
- if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message has been buffered - load" ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered handshake message (incl. header)",
- hs_buf->data, msg_len + 12 );
-
- ssl->in_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
- ssl->in_hslen = msg_len + 12;
- ssl->in_msglen = msg_len + 12;
- memcpy( ssl->in_msg, hs_buf->data, ssl->in_hslen );
-
- ret = 0;
- goto exit;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Next handshake message %u not or only partially bufffered",
- hs->in_msg_seq ) );
- }
-
- ret = -1;
-
-exit:
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_message" ) );
- return( ret );
-}
-
-static int ssl_buffer_make_space( mbedtls_ssl_context *ssl,
- size_t desired )
-{
- int offset;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Attempt to free buffered messages to have %u bytes available",
- (unsigned) desired ) );
-
- /* Get rid of future records epoch first, if such exist. */
- ssl_free_buffered_record( ssl );
-
- /* Check if we have enough space available now. */
- if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing future epoch record" ) );
- return( 0 );
- }
-
- /* We don't have enough space to buffer the next expected handshake
- * message. Remove buffers used for future messages to gain space,
- * starting with the most distant one. */
- for( offset = MBEDTLS_SSL_MAX_BUFFERED_HS - 1;
- offset >= 0; offset-- )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Free buffering slot %d to make space for reassembly of next handshake message",
- offset ) );
-
- ssl_buffering_free_slot( ssl, (uint8_t) offset );
-
- /* Check if we have enough space available now. */
- if( desired <= ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Enough space available after freeing buffered HS messages" ) );
- return( 0 );
- }
- }
-
- return( -1 );
-}
-
-static int ssl_buffer_message( mbedtls_ssl_context *ssl )
-{
- int ret = 0;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
-
- if( hs == NULL )
- return( 0 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_buffer_message" ) );
-
- switch( ssl->in_msgtype )
- {
- case MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Remember CCS message" ) );
-
- hs->buffering.seen_ccs = 1;
- break;
-
- case MBEDTLS_SSL_MSG_HANDSHAKE:
- {
- unsigned recv_msg_seq_offset;
- unsigned recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
- mbedtls_ssl_hs_buffer *hs_buf;
- size_t msg_len = ssl->in_hslen - 12;
-
- /* We should never receive an old handshake
- * message - double-check nonetheless. */
- if( recv_msg_seq < ssl->handshake->in_msg_seq )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- recv_msg_seq_offset = recv_msg_seq - ssl->handshake->in_msg_seq;
- if( recv_msg_seq_offset >= MBEDTLS_SSL_MAX_BUFFERED_HS )
- {
- /* Silently ignore -- message too far in the future */
- MBEDTLS_SSL_DEBUG_MSG( 2,
- ( "Ignore future HS message with sequence number %u, "
- "buffering window %u - %u",
- recv_msg_seq, ssl->handshake->in_msg_seq,
- ssl->handshake->in_msg_seq + MBEDTLS_SSL_MAX_BUFFERED_HS - 1 ) );
-
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering HS message with sequence number %u, offset %u ",
- recv_msg_seq, recv_msg_seq_offset ) );
-
- hs_buf = &hs->buffering.hs[ recv_msg_seq_offset ];
-
- /* Check if the buffering for this seq nr has already commenced. */
- if( !hs_buf->is_valid )
- {
- size_t reassembly_buf_sz;
-
- hs_buf->is_fragmented =
- ( ssl_hs_is_proper_fragment( ssl ) == 1 );
-
- /* We copy the message back into the input buffer
- * after reassembly, so check that it's not too large.
- * This is an implementation-specific limitation
- * and not one from the standard, hence it is not
- * checked in ssl_check_hs_header(). */
- if( msg_len + 12 > MBEDTLS_SSL_IN_CONTENT_LEN )
- {
- /* Ignore message */
- goto exit;
- }
-
- /* Check if we have enough space to buffer the message. */
- if( hs->buffering.total_bytes_buffered >
- MBEDTLS_SSL_DTLS_MAX_BUFFERING )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- reassembly_buf_sz = ssl_get_reassembly_buffer_size( msg_len,
- hs_buf->is_fragmented );
-
- if( reassembly_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- if( recv_msg_seq_offset > 0 )
- {
- /* If we can't buffer a future message because
- * of space limitations -- ignore. */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
- (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- goto exit;
- }
- else
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future message of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- attempt to make space by freeing buffered future messages\n",
- (unsigned) msg_len, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- }
-
- if( ssl_buffer_make_space( ssl, reassembly_buf_sz ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reassembly of next message of size %u (%u with bitmap) would exceed the compile-time limit %u (already %u bytes buffered) -- fail\n",
- (unsigned) msg_len,
- (unsigned) reassembly_buf_sz,
- MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- ret = MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
- goto exit;
- }
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d",
- msg_len ) );
-
- hs_buf->data = mbedtls_calloc( 1, reassembly_buf_sz );
- if( hs_buf->data == NULL )
- {
- ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
- goto exit;
- }
- hs_buf->data_len = reassembly_buf_sz;
-
- /* Prepare final header: copy msg_type, length and message_seq,
- * then add standardised fragment_offset and fragment_length */
- memcpy( hs_buf->data, ssl->in_msg, 6 );
- memset( hs_buf->data + 6, 0, 3 );
- memcpy( hs_buf->data + 9, hs_buf->data + 1, 3 );
-
- hs_buf->is_valid = 1;
-
- hs->buffering.total_bytes_buffered += reassembly_buf_sz;
- }
- else
- {
- /* Make sure msg_type and length are consistent */
- if( memcmp( hs_buf->data, ssl->in_msg, 4 ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "Fragment header mismatch - ignore" ) );
- /* Ignore */
- goto exit;
- }
- }
-
- if( !hs_buf->is_complete )
- {
- size_t frag_len, frag_off;
- unsigned char * const msg = hs_buf->data + 12;
-
- /*
- * Check and copy current fragment
- */
-
- /* Validation of header fields already done in
- * mbedtls_ssl_prepare_handshake_record(). */
- frag_off = ssl_get_hs_frag_off( ssl );
- frag_len = ssl_get_hs_frag_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d",
- frag_off, frag_len ) );
- memcpy( msg + frag_off, ssl->in_msg + 12, frag_len );
-
- if( hs_buf->is_fragmented )
- {
- unsigned char * const bitmask = msg + msg_len;
- ssl_bitmask_set( bitmask, frag_off, frag_len );
- hs_buf->is_complete = ( ssl_bitmask_check( bitmask,
- msg_len ) == 0 );
- }
- else
- {
- hs_buf->is_complete = 1;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "message %scomplete",
- hs_buf->is_complete ? "" : "not yet " ) );
- }
-
- break;
- }
-
- default:
- /* We don't buffer other types of messages. */
- break;
- }
-
-exit:
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_buffer_message" ) );
- return( ret );
-}
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static int ssl_consume_current_message( mbedtls_ssl_context *ssl )
-{
- /*
- * Consume last content-layer message and potentially
- * update in_msglen which keeps track of the contents'
- * consumption state.
- *
- * (1) Handshake messages:
- * Remove last handshake message, move content
- * and adapt in_msglen.
- *
- * (2) Alert messages:
- * Consume whole record content, in_msglen = 0.
- *
- * (3) Change cipher spec:
- * Consume whole record content, in_msglen = 0.
- *
- * (4) Application data:
- * Don't do anything - the record layer provides
- * the application data as a stream transport
- * and consumes through mbedtls_ssl_read only.
- *
- */
-
- /* Case (1): Handshake messages */
- if( ssl->in_hslen != 0 )
- {
- /* Hard assertion to be sure that no application data
- * is in flight, as corrupting ssl->in_msglen during
- * ssl->in_offt != NULL is fatal. */
- if( ssl->in_offt != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- /*
- * Get next Handshake message in the current record
- */
-
- /* Notes:
- * (1) in_hslen is not necessarily the size of the
- * current handshake content: If DTLS handshake
- * fragmentation is used, that's the fragment
- * size instead. Using the total handshake message
- * size here is faulty and should be changed at
- * some point.
- * (2) While it doesn't seem to cause problems, one
- * has to be very careful not to assume that in_hslen
- * is always <= in_msglen in a sensible communication.
- * Again, it's wrong for DTLS handshake fragmentation.
- * The following check is therefore mandatory, and
- * should not be treated as a silently corrected assertion.
- * Additionally, ssl->in_hslen might be arbitrarily out of
- * bounds after handling a DTLS message with an unexpected
- * sequence number, see mbedtls_ssl_prepare_handshake_record.
- */
- if( ssl->in_hslen < ssl->in_msglen )
- {
- ssl->in_msglen -= ssl->in_hslen;
- memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen,
- ssl->in_msglen );
-
- MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
- ssl->in_msg, ssl->in_msglen );
- }
- else
- {
- ssl->in_msglen = 0;
- }
-
- ssl->in_hslen = 0;
- }
- /* Case (4): Application data */
- else if( ssl->in_offt != NULL )
- {
- return( 0 );
- }
- /* Everything else (CCS & Alerts) */
- else
- {
- ssl->in_msglen = 0;
- }
-
- return( 0 );
-}
-
-static int ssl_record_is_in_progress( mbedtls_ssl_context *ssl )
-{
- if( ssl->in_msglen > 0 )
- return( 1 );
-
- return( 0 );
-}
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-
-static void ssl_free_buffered_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- if( hs == NULL )
- return;
-
- if( hs->buffering.future_record.data != NULL )
- {
- hs->buffering.total_bytes_buffered -=
- hs->buffering.future_record.len;
-
- mbedtls_free( hs->buffering.future_record.data );
- hs->buffering.future_record.data = NULL;
- }
-}
-
-static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- unsigned char * rec;
- size_t rec_len;
- unsigned rec_epoch;
-
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 0 );
-
- if( hs == NULL )
- return( 0 );
-
- rec = hs->buffering.future_record.data;
- rec_len = hs->buffering.future_record.len;
- rec_epoch = hs->buffering.future_record.epoch;
-
- if( rec == NULL )
- return( 0 );
-
- /* Only consider loading future records if the
- * input buffer is empty. */
- if( ssl_next_record_is_in_datagram( ssl ) == 1 )
- return( 0 );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> ssl_load_buffered_record" ) );
-
- if( rec_epoch != ssl->in_epoch )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffered record not from current epoch." ) );
- goto exit;
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
-
- /* Double-check that the record is not too large */
- if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN -
- (size_t)( ssl->in_hdr - ssl->in_buf ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
-
- memcpy( ssl->in_hdr, rec, rec_len );
- ssl->in_left = rec_len;
- ssl->next_record_offset = 0;
-
- ssl_free_buffered_record( ssl );
-
-exit:
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_load_buffered_record" ) );
- return( 0 );
-}
-
-static int ssl_buffer_future_record( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- size_t const rec_hdr_len = 13;
- size_t const total_buf_sz = rec_hdr_len + ssl->in_msglen;
-
- /* Don't buffer future records outside handshakes. */
- if( hs == NULL )
- return( 0 );
-
- /* Only buffer handshake records (we are only interested
- * in Finished messages). */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
- return( 0 );
-
- /* Don't buffer more than one future epoch record. */
- if( hs->buffering.future_record.data != NULL )
- return( 0 );
-
- /* Don't buffer record if there's not enough buffering space remaining. */
- if( total_buf_sz > ( MBEDTLS_SSL_DTLS_MAX_BUFFERING -
- hs->buffering.total_bytes_buffered ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffering of future epoch record of size %u would exceed the compile-time limit %u (already %u bytes buffered) -- ignore\n",
- (unsigned) total_buf_sz, MBEDTLS_SSL_DTLS_MAX_BUFFERING,
- (unsigned) hs->buffering.total_bytes_buffered ) );
- return( 0 );
- }
-
- /* Buffer record */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "Buffer record from epoch %u",
- ssl->in_epoch + 1 ) );
- MBEDTLS_SSL_DEBUG_BUF( 3, "Buffered record", ssl->in_hdr,
- rec_hdr_len + ssl->in_msglen );
-
- /* ssl_parse_record_header() only considers records
- * of the next epoch as candidates for buffering. */
- hs->buffering.future_record.epoch = ssl->in_epoch + 1;
- hs->buffering.future_record.len = total_buf_sz;
-
- hs->buffering.future_record.data =
- mbedtls_calloc( 1, hs->buffering.future_record.len );
- if( hs->buffering.future_record.data == NULL )
- {
- /* If we run out of RAM trying to buffer a
- * record from the next epoch, just ignore. */
- return( 0 );
- }
-
- memcpy( hs->buffering.future_record.data, ssl->in_hdr, total_buf_sz );
-
- hs->buffering.total_bytes_buffered += total_buf_sz;
- return( 0 );
-}
-
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-static int ssl_get_next_record( mbedtls_ssl_context *ssl )
-{
- int ret;
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* We might have buffered a future record; if so,
- * and if the epoch matches now, load it.
- * On success, this call will set ssl->in_left to
- * the length of the buffered record, so that
- * the calls to ssl_fetch_input() below will
- * essentially be no-ops. */
- ret = ssl_load_buffered_record( ssl );
- if( ret != 0 )
- return( ret );
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
-
- if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
- {
- if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
- {
- ret = ssl_buffer_future_record( ssl );
- if( ret != 0 )
- return( ret );
-
- /* Fall through to handling of unexpected records */
- ret = MBEDTLS_ERR_SSL_UNEXPECTED_RECORD;
- }
-
- if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
- {
- /* Skip unexpected record (but not whole datagram) */
- ssl->next_record_offset = ssl->in_msglen
- + mbedtls_ssl_hdr_len( ssl );
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
- "(header)" ) );
- }
- else
- {
- /* Skip invalid record and the rest of the datagram */
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
- "(header)" ) );
- }
-
- /* Get next record */
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
-#endif
- return( ret );
- }
-
- /*
- * Read and optionally decrypt the message contents
- */
- if( ( ret = mbedtls_ssl_fetch_input( ssl,
- mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
- return( ret );
- }
-
- /* Done reading this record, get ready for the next one */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl );
- if( ssl->next_record_offset < ssl->in_left )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
- }
- }
- else
-#endif
- ssl->in_left = 0;
-
- if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- /* Silently discard invalid records */
- if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD ||
- ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- /* Except when waiting for Finished as a bad mac here
- * probably means something went wrong in the handshake
- * (eg wrong psk used, mitm downgrade attempt, etc.) */
- if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED ||
- ssl->state == MBEDTLS_SSL_SERVER_FINISHED )
- {
-#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
-#endif
- return( ret );
- }
-
-#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
- if( ssl->conf->badmac_limit != 0 &&
- ++ssl->badmac_seen >= ssl->conf->badmac_limit )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) );
- return( MBEDTLS_ERR_SSL_INVALID_MAC );
- }
-#endif
-
- /* As above, invalid records cause
- * dismissal of the whole datagram. */
-
- ssl->next_record_offset = 0;
- ssl->in_left = 0;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) );
- return( MBEDTLS_ERR_SSL_CONTINUE_PROCESSING );
- }
-
- return( ret );
- }
- else
-#endif
- {
- /* Error out (and send alert) on invalid records */
-#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
- if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
- {
- mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC );
- }
-#endif
- return( ret );
- }
- }
-
- return( 0 );
-}
-
-int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
-{
- int ret;
-
- /*
- * Handle particular types of records
- */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 )
- {
- return( ret );
- }
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- if( ssl->in_msglen != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, len: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- if( ssl->in_msg[0] != 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid CCS message, content: %02x",
- ssl->in_msg[0] ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
- ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
- {
- if( ssl->handshake == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping ChangeCipherSpec outside handshake" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received out-of-order ChangeCipherSpec - remember" ) );
- return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
- }
-#endif
- }
-
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- if( ssl->in_msglen != 2 )
- {
- /* Note: Standard allows for more than one 2 byte alert
- to be packed in a single message, but Mbed TLS doesn't
- currently support this. */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d",
- ssl->in_msglen ) );
- return( MBEDTLS_ERR_SSL_INVALID_RECORD );
- }
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]",
- ssl->in_msg[0], ssl->in_msg[1] ) );
-
- /*
- * Ignore non-fatal alerts, except close_notify and no_renegotiation
- */
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)",
- ssl->in_msg[1] ) );
- return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE );
- }
-
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
- return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
- }
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
- if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no renegotiation alert" ) );
- /* Will be handled when trying to parse ServerHello */
- return( 0 );
- }
-#endif
-
-#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
- /* Will be handled in mbedtls_ssl_parse_certificate() */
- return( 0 );
- }
-#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
-
- /* Silently ignore: fetch new message */
- return MBEDTLS_ERR_SSL_NON_FATAL;
- }
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->handshake != NULL &&
- ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ssl_handshake_wrapup_free_hs_transform( ssl );
- }
-#endif
-
- return( 0 );
-}
-
-int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void ssl_clear_peer_cert( mbedtls_ssl_session *session )
{
- int ret;
-
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 )
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( session->peer_cert != NULL )
{
- return( ret );
+ mbedtls_x509_crt_free( session->peer_cert );
+ mbedtls_free( session->peer_cert );
+ session->peer_cert = NULL;
}
-
- return( 0 );
-}
-
-int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
- unsigned char level,
- unsigned char message )
-{
- int ret;
-
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) );
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message ));
-
- ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT;
- ssl->out_msglen = 2;
- ssl->out_msg[0] = level;
- ssl->out_msg[1] = message;
-
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( session->peer_cert_digest != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
+ /* Zeroization is not necessary. */
+ mbedtls_free( session->peer_cert_digest );
+ session->peer_cert_digest = NULL;
+ session->peer_cert_digest_type = MBEDTLS_MD_NONE;
+ session->peer_cert_digest_len = 0;
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) );
-
- return( 0 );
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
/*
* Handshake functions
*/
-#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
- !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
+#if !defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* No certificate support -> dummy functions */
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
{
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++;
@@ -5578,14 +2186,12 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++;
@@ -5596,7 +2202,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
-#else
+#else /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/* Some certificate support -> implement write and parse */
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
@@ -5604,14 +2210,12 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
size_t i, n;
const mbedtls_x509_crt *crt;
- const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++;
@@ -5677,22 +2281,23 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
n = crt->raw.len;
if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d",
- i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %" MBEDTLS_PRINTF_SIZET
+ " > %" MBEDTLS_PRINTF_SIZET,
+ i + 3 + n, (size_t) MBEDTLS_SSL_OUT_CONTENT_LEN ) );
return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE );
}
- ssl->out_msg[i ] = (unsigned char)( n >> 16 );
- ssl->out_msg[i + 1] = (unsigned char)( n >> 8 );
- ssl->out_msg[i + 2] = (unsigned char)( n );
+ ssl->out_msg[i ] = MBEDTLS_BYTE_2( n );
+ ssl->out_msg[i + 1] = MBEDTLS_BYTE_1( n );
+ ssl->out_msg[i + 2] = MBEDTLS_BYTE_0( n );
i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n );
i += n; crt = crt->next;
}
- ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 );
- ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 );
- ssl->out_msg[6] = (unsigned char)( ( i - 7 ) );
+ ssl->out_msg[4] = MBEDTLS_BYTE_2( i - 7 );
+ ssl->out_msg[5] = MBEDTLS_BYTE_1( i - 7 );
+ ssl->out_msg[6] = MBEDTLS_BYTE_0( i - 7 );
ssl->out_msglen = i;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
@@ -5715,63 +2320,68 @@ write_msg:
return( ret );
}
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+ unsigned char *crt_buf,
+ size_t crt_buf_len )
+{
+ mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
+
+ if( peer_crt == NULL )
+ return( -1 );
+
+ if( peer_crt->raw.len != crt_buf_len )
+ return( -1 );
+
+ return( memcmp( peer_crt->raw.p, crt_buf, peer_crt->raw.len ) );
+}
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+ unsigned char *crt_buf,
+ size_t crt_buf_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ unsigned char const * const peer_cert_digest =
+ ssl->session->peer_cert_digest;
+ mbedtls_md_type_t const peer_cert_digest_type =
+ ssl->session->peer_cert_digest_type;
+ mbedtls_md_info_t const * const digest_info =
+ mbedtls_md_info_from_type( peer_cert_digest_type );
+ unsigned char tmp_digest[MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN];
+ size_t digest_len;
+
+ if( peer_cert_digest == NULL || digest_info == NULL )
+ return( -1 );
+
+ digest_len = mbedtls_md_get_size( digest_info );
+ if( digest_len > MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN )
+ return( -1 );
+
+ ret = mbedtls_md( digest_info, crt_buf, crt_buf_len, tmp_digest );
+ if( ret != 0 )
+ return( -1 );
+
+ return( memcmp( tmp_digest, peer_cert_digest, digest_len ) );
+}
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
/*
* Once the certificate message is read, parse it into a cert chain and
* perform basic checks, but leave actual verification to the caller
*/
-static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
+static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl,
+ mbedtls_x509_crt *chain )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+ int crt_cnt=0;
+#endif
size_t i, n;
uint8_t alert;
-#if defined(MBEDTLS_SSL_SRV_C)
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- /*
- * Check if the client sent an empty certificate
- */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_msglen == 2 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
- ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
- ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
-
- /* The client was asked for a certificate but didn't send
- one. The client should know what's going on, so we
- don't send an alert. */
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
- ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
- memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
-
- /* The client was asked for a certificate but didn't send
- one. The client should know what's going on, so we
- don't send an alert. */
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE );
- }
- }
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
- MBEDTLS_SSL_PROTO_TLS1_2 */
-#endif /* MBEDTLS_SSL_SRV_C */
-
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
@@ -5805,43 +2415,32 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
- /* In case we tried to reuse a session but it failed */
- if( ssl->session_negotiate->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
- mbedtls_free( ssl->session_negotiate->peer_cert );
- }
-
- if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
- sizeof( mbedtls_x509_crt ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- sizeof( mbedtls_x509_crt ) ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
-
+ /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
i += 3;
+ /* Iterate through and parse the CRTs in the provided chain. */
while( i < ssl->in_hslen )
{
+ /* Check that there's room for the next CRT's length fields. */
if ( i + 3 > ssl->in_hslen ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
+ * anything beyond 2**16 ~ 64K. */
if( ssl->in_msg[i] != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* Read length of the next CRT in the chain. */
n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
| (unsigned int) ssl->in_msg[i + 2];
i += 3;
@@ -5849,161 +2448,207 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl )
if( n < 128 || i + n > ssl->in_hslen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
- ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
- ssl->in_msg + i, n );
+ /* Check if we're handling the first CRT in the chain. */
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+ if( crt_cnt++ == 0 &&
+ ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+ {
+ /* During client-side renegotiation, check that the server's
+ * end-CRTs hasn't changed compared to the initial handshake,
+ * mitigating the triple handshake attack. On success, reuse
+ * the original end-CRT instead of parsing it again. */
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
+ if( ssl_check_peer_crt_unchanged( ssl,
+ &ssl->in_msg[i],
+ n ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+ }
+
+ /* Now we can safely free the original chain. */
+ ssl_clear_peer_cert( ssl->session );
+ }
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+ /* Parse the next certificate in the chain. */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ ret = mbedtls_x509_crt_parse_der( chain, ssl->in_msg + i, n );
+#else
+ /* If we don't need to store the CRT chain permanently, parse
+ * it in-place from the input buffer instead of making a copy. */
+ ret = mbedtls_x509_crt_parse_der_nocopy( chain, ssl->in_msg + i, n );
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
switch( ret )
{
- case 0: /*ok*/
- case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
- /* Ignore certificate with an unknown algorithm: maybe a
- prior certificate was already trusted. */
- break;
+ case 0: /*ok*/
+ case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
+ /* Ignore certificate with an unknown algorithm: maybe a
+ prior certificate was already trusted. */
+ break;
- case MBEDTLS_ERR_X509_ALLOC_FAILED:
- alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_ALLOC_FAILED:
+ alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
+ goto crt_parse_der_failed;
- case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ goto crt_parse_der_failed;
- default:
- alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
- crt_parse_der_failed:
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
- MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
- return( ret );
+ default:
+ alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+ crt_parse_der_failed:
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+ MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
+ return( ret );
}
i += n;
}
- MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
+ MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", chain );
+ return( 0 );
+}
+#if defined(MBEDTLS_SSL_SRV_C)
+static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl )
+{
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
+ return( -1 );
+
+#if defined(MBEDTLS_SSL_PROTO_SSL3)
/*
- * On client, make sure the server cert doesn't change during renego to
- * avoid "triple handshake" attack: https://secure-resumption.com/
+ * Check if the client sent an empty certificate
*/
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{
- if( ssl->session->peer_cert == NULL )
+ if( ssl->in_msglen == 2 &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT &&
+ ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
+ ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) );
+ return( 0 );
}
- if( ssl->session->peer_cert->raw.len !=
- ssl->session_negotiate->peer_cert->raw.len ||
- memcmp( ssl->session->peer_cert->raw.p,
- ssl->session_negotiate->peer_cert->raw.p,
- ssl->session->peer_cert->raw.len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
+ return( -1 );
}
-#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+#endif /* MBEDTLS_SSL_PROTO_SSL3 */
- return( 0 );
+#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_2)
+ if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) &&
+ ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE &&
+ memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) );
+ return( 0 );
+ }
+
+ return( -1 );
+#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
+ MBEDTLS_SSL_PROTO_TLS1_2 */
}
+#endif /* MBEDTLS_SSL_SRV_C */
-int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+/* Check if a certificate message is expected.
+ * Return either
+ * - SSL_CERTIFICATE_EXPECTED, or
+ * - SSL_CERTIFICATE_SKIP
+ * indicating whether a Certificate message is expected or not.
+ */
+#define SSL_CERTIFICATE_EXPECTED 0
+#define SSL_CERTIFICATE_SKIP 1
+static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl,
+ int authmode )
{
- int ret;
- const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
- ssl->transform_negotiate->ciphersuite_info;
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
- ? ssl->handshake->sni_authmode
- : ssl->conf->authmode;
-#else
- const int authmode = ssl->conf->authmode;
-#endif
- void *rs_ctx = NULL;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
-
- if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
- }
+ if( !mbedtls_ssl_ciphersuite_uses_srv_cert( ciphersuite_info ) )
+ return( SSL_CERTIFICATE_SKIP );
#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- ssl->state++;
- return( 0 );
+ if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
+ return( SSL_CERTIFICATE_SKIP );
+
+ if( authmode == MBEDTLS_SSL_VERIFY_NONE )
+ {
+ ssl->session_negotiate->verify_result =
+ MBEDTLS_X509_BADCERT_SKIP_VERIFY;
+ return( SSL_CERTIFICATE_SKIP );
+ }
}
+#else
+ ((void) authmode);
+#endif /* MBEDTLS_SSL_SRV_C */
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- authmode == MBEDTLS_SSL_VERIFY_NONE )
- {
- ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY;
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+ return( SSL_CERTIFICATE_EXPECTED );
+}
- ssl->state++;
+static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
+ int authmode,
+ mbedtls_x509_crt *chain,
+ void *rs_ctx )
+{
+ int ret = 0;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
+ ssl->handshake->ciphersuite_info;
+ int have_ca_chain = 0;
+
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *);
+ void *p_vrfy;
+
+ if( authmode == MBEDTLS_SSL_VERIFY_NONE )
return( 0 );
- }
-#endif
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ssl->handshake->ecrs_enabled &&
- ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+ if( ssl->f_vrfy != NULL )
{
- goto crt_verify;
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) );
+ f_vrfy = ssl->f_vrfy;
+ p_vrfy = ssl->p_vrfy;
}
-#endif
-
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
+ else
{
- /* mbedtls_ssl_read_record may have sent an alert already. We
- let it decide whether to alert. */
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) );
+ f_vrfy = ssl->conf->f_vrfy;
+ p_vrfy = ssl->conf->p_vrfy;
}
- if( ( ret = ssl_parse_certificate_chain( ssl ) ) != 0 )
- {
-#if defined(MBEDTLS_SSL_SRV_C)
- if( ret == MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE &&
- authmode == MBEDTLS_SSL_VERIFY_OPTIONAL )
- {
- ret = 0;
- }
-#endif
-
- ssl->state++;
- return( ret );
+ /*
+ * Main check: verify certificate
+ */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ if( ssl->conf->f_ca_cb != NULL )
+ {
+ ((void) rs_ctx);
+ have_ca_chain = 1;
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "use CA callback for X.509 CRT verification" ) );
+ ret = mbedtls_x509_crt_verify_with_ca_cb(
+ chain,
+ ssl->conf->f_ca_cb,
+ ssl->conf->p_ca_cb,
+ ssl->conf->cert_profile,
+ ssl->hostname,
+ &ssl->session_negotiate->verify_result,
+ f_vrfy, p_vrfy );
}
-
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ssl->handshake->ecrs_enabled)
- ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
-
-crt_verify:
- if( ssl->handshake->ecrs_enabled)
- rs_ctx = &ssl->handshake->ecrs_ctx;
-#endif
-
- if( authmode != MBEDTLS_SSL_VERIFY_NONE )
+ else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
{
mbedtls_x509_crt *ca_chain;
mbedtls_x509_crl *ca_crl;
@@ -6021,232 +2666,327 @@ crt_verify:
ca_crl = ssl->conf->ca_crl;
}
- /*
- * Main check: verify certificate
- */
+ if( ca_chain != NULL )
+ have_ca_chain = 1;
+
ret = mbedtls_x509_crt_verify_restartable(
- ssl->session_negotiate->peer_cert,
- ca_chain, ca_crl,
- ssl->conf->cert_profile,
- ssl->hostname,
- &ssl->session_negotiate->verify_result,
- ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx );
+ chain,
+ ca_chain, ca_crl,
+ ssl->conf->cert_profile,
+ ssl->hostname,
+ &ssl->session_negotiate->verify_result,
+ f_vrfy, p_vrfy, rs_ctx );
+ }
- if( ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
- }
+ if( ret != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret );
+ }
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
- return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
+ return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS );
#endif
- /*
- * Secondary checks: always done, but change 'ret' only if it was 0
- */
+ /*
+ * Secondary checks: always done, but change 'ret' only if it was 0
+ */
#if defined(MBEDTLS_ECP_C)
- {
- const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk;
-
- /* If certificate uses an EC key, make sure the curve is OK */
- if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
- mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
- {
- ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
-
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
- if( ret == 0 )
- ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
- }
- }
-#endif /* MBEDTLS_ECP_C */
+ {
+ const mbedtls_pk_context *pk = &chain->pk;
- if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
- ciphersuite_info,
- ! ssl->conf->endpoint,
- &ssl->session_negotiate->verify_result ) != 0 )
+ /* If certificate uses an EC key, make sure the curve is OK */
+ if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) &&
+ mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+ ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY;
+
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) );
if( ret == 0 )
ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
}
+ }
+#endif /* MBEDTLS_ECP_C */
- /* mbedtls_x509_crt_verify_with_profile is supposed to report a
- * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
- * with details encoded in the verification flags. All other kinds
- * of error codes, including those from the user provided f_vrfy
- * functions, are treated as fatal and lead to a failure of
- * ssl_parse_certificate even if verification was optional. */
- if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
- ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
- ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
- {
- ret = 0;
- }
+ if( mbedtls_ssl_check_cert_usage( chain,
+ ciphersuite_info,
+ ! ssl->conf->endpoint,
+ &ssl->session_negotiate->verify_result ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
+ if( ret == 0 )
+ ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE;
+ }
- if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
- ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
- }
+ /* mbedtls_x509_crt_verify_with_profile is supposed to report a
+ * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED,
+ * with details encoded in the verification flags. All other kinds
+ * of error codes, including those from the user provided f_vrfy
+ * functions, are treated as fatal and lead to a failure of
+ * ssl_parse_certificate even if verification was optional. */
+ if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL &&
+ ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ||
+ ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) )
+ {
+ ret = 0;
+ }
- if( ret != 0 )
- {
- uint8_t alert;
-
- /* The certificate may have been rejected for several reasons.
- Pick one and send the corresponding alert. Which alert to send
- may be a subject of debate in some cases. */
- if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
- alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
- alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
- else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
- alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
- else
- alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- alert );
- }
+ if( have_ca_chain == 0 && authmode == MBEDTLS_SSL_VERIFY_REQUIRED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) );
+ ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED;
+ }
-#if defined(MBEDTLS_DEBUG_C)
- if( ssl->session_negotiate->verify_result != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x",
- ssl->session_negotiate->verify_result ) );
- }
+ if( ret != 0 )
+ {
+ uint8_t alert;
+
+ /* The certificate may have been rejected for several reasons.
+ Pick one and send the corresponding alert. Which alert to send
+ may be a subject of debate in some cases. */
+ if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER )
+ alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH )
+ alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED )
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED )
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED;
+ else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED )
+ alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA;
else
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
- }
-#endif /* MBEDTLS_DEBUG_C */
+ alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN;
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ alert );
}
- ssl->state++;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
+#if defined(MBEDTLS_DEBUG_C)
+ if( ssl->session_negotiate->verify_result != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %08x",
+ (unsigned int) ssl->session_negotiate->verify_result ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) );
+ }
+#endif /* MBEDTLS_DEBUG_C */
return( ret );
}
-#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
- !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
- !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
-int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl )
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+static int ssl_remember_peer_crt_digest( mbedtls_ssl_context *ssl,
+ unsigned char *start, size_t len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Remember digest of the peer's end-CRT. */
+ ssl->session_negotiate->peer_cert_digest =
+ mbedtls_calloc( 1, MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN );
+ if( ssl->session_negotiate->peer_cert_digest == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) );
+ ret = mbedtls_md( mbedtls_md_info_from_type(
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE ),
+ start, len,
+ ssl->session_negotiate->peer_cert_digest );
- ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC;
- ssl->out_msglen = 1;
- ssl->out_msg[0] = 1;
+ ssl->session_negotiate->peer_cert_digest_type =
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE;
+ ssl->session_negotiate->peer_cert_digest_len =
+ MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN;
- ssl->state++;
+ return( ret );
+}
- if( ( ret = mbedtls_ssl_write_handshake_msg( ssl ) ) != 0 )
+static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
+ unsigned char *start, size_t len )
+{
+ unsigned char *end = start + len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ /* Make a copy of the peer's raw public key. */
+ mbedtls_pk_init( &ssl->handshake->peer_pubkey );
+ ret = mbedtls_pk_parse_subpubkey( &start, end,
+ &ssl->handshake->peer_pubkey );
+ if( ret != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_handshake_msg", ret );
- return( ret );
+ /* We should have parsed the public key before. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) );
-
return( 0 );
}
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = 0;
+ int crt_expected;
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+ ? ssl->handshake->sni_authmode
+ : ssl->conf->authmode;
+#else
+ const int authmode = ssl->conf->authmode;
+#endif
+ void *rs_ctx = NULL;
+ mbedtls_x509_crt *chain = NULL;
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
+
+ crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
+ if( crt_expected == SSL_CERTIFICATE_SKIP )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+ goto exit;
+ }
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) );
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ssl->handshake->ecrs_enabled &&
+ ssl->handshake->ecrs_state == ssl_ecrs_crt_verify )
+ {
+ chain = ssl->handshake->ecrs_peer_cert;
+ ssl->handshake->ecrs_peer_cert = NULL;
+ goto crt_verify;
+ }
+#endif
if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
{
+ /* mbedtls_ssl_read_record may have sent an alert already. We
+ let it decide whether to alert. */
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
+ goto exit;
}
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+#if defined(MBEDTLS_SSL_SRV_C)
+ if( ssl_srv_check_client_no_crt_notification( ssl ) == 0 )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
+ ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING;
- /* CCS records are only accepted if they have length 1 and content '1',
- * so we don't need to check this here. */
+ if( authmode != MBEDTLS_SSL_VERIFY_OPTIONAL )
+ ret = MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE;
- /*
- * Switch to our negotiated transform and session parameters for inbound
- * data.
- */
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) );
- ssl->transform_in = ssl->transform_negotiate;
- ssl->session_in = ssl->session_negotiate;
+ goto exit;
+ }
+#endif /* MBEDTLS_SSL_SRV_C */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ /* Clear existing peer CRT structure in case we tried to
+ * reuse a session but it failed, and allocate a new one. */
+ ssl_clear_peer_cert( ssl->session_negotiate );
+
+ chain = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+ if( chain == NULL )
{
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed",
+ sizeof( mbedtls_x509_crt ) ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+
+ ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
+ goto exit;
+ }
+ mbedtls_x509_crt_init( chain );
+
+ ret = ssl_parse_certificate_chain( ssl, chain );
+ if( ret != 0 )
+ goto exit;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ssl->handshake->ecrs_enabled)
+ ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
+
+crt_verify:
+ if( ssl->handshake->ecrs_enabled)
+ rs_ctx = &ssl->handshake->ecrs_ctx;
#endif
- /* Increment epoch */
- if( ++ssl->in_epoch == 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) );
- /* This is highly unlikely to happen for legitimate reasons, so
- treat it as an attack and don't send an alert. */
- return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
- }
+ ret = ssl_parse_certificate_verify( ssl, authmode,
+ chain, rs_ctx );
+ if( ret != 0 )
+ goto exit;
+
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ {
+ unsigned char *crt_start, *pk_start;
+ size_t crt_len, pk_len;
+
+ /* We parse the CRT chain without copying, so
+ * these pointers point into the input buffer,
+ * and are hence still valid after freeing the
+ * CRT chain. */
+
+ crt_start = chain->raw.p;
+ crt_len = chain->raw.len;
+
+ pk_start = chain->pk_raw.p;
+ pk_len = chain->pk_raw.len;
+
+ /* Free the CRT structures before computing
+ * digest and copying the peer's public key. */
+ mbedtls_x509_crt_free( chain );
+ mbedtls_free( chain );
+ chain = NULL;
+
+ ret = ssl_remember_peer_crt_digest( ssl, crt_start, crt_len );
+ if( ret != 0 )
+ goto exit;
+
+ ret = ssl_remember_peer_pubkey( ssl, pk_start, pk_len );
+ if( ret != 0 )
+ goto exit;
}
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->in_ctr, 0, 8 );
+#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Pass ownership to session structure. */
+ ssl->session_negotiate->peer_cert = chain;
+ chain = NULL;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- ssl_update_in_pointers( ssl, ssl->transform_negotiate );
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) );
-#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
- if( mbedtls_ssl_hw_record_activate != NULL )
+exit:
+
+ if( ret == 0 )
+ ssl->state++;
+
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ if( ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS )
{
- if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
- }
+ ssl->handshake->ecrs_peer_cert = chain;
+ chain = NULL;
}
#endif
- ssl->state++;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) );
+ if( chain != NULL )
+ {
+ mbedtls_x509_crt_free( chain );
+ mbedtls_free( chain );
+ }
- return( 0 );
+ return( ret );
}
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
const mbedtls_ssl_ciphersuite_t *ciphersuite_info )
@@ -6260,7 +3000,7 @@ void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl,
else
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
ssl->handshake->update_checksum = ssl_update_checksum_sha384;
else
@@ -6286,11 +3026,21 @@ void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha256_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_starts_ret( &ssl->handshake->fin_sha256, 0 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &ssl->handshake->fin_sha384_psa );
+ psa_hash_setup( &ssl->handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_starts_ret( &ssl->handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6304,11 +3054,19 @@ static void ssl_update_checksum_start( mbedtls_ssl_context *ssl,
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
}
@@ -6327,15 +3085,23 @@ static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl,
static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha256_psa, buf, len );
+#else
mbedtls_sha256_update_ret( &ssl->handshake->fin_sha256, buf, len );
+#endif
}
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_update( &ssl->handshake->fin_sha384_psa, buf, len );
+#else
mbedtls_sha512_update_ret( &ssl->handshake->fin_sha512, buf, len );
+#endif
}
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
@@ -6491,13 +3257,44 @@ static void ssl_calc_finished_tls_sha256(
{
int len = 12;
const char *sender;
- mbedtls_sha256_context sha256;
unsigned char padbuf[32];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha256_psa = PSA_HASH_OPERATION_INIT;
+ psa_status_t status;
+#else
+ mbedtls_sha256_context sha256;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha256_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha256" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha256_psa, &sha256_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha256_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 32 );
+#else
+
mbedtls_sha256_init( &sha256 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) );
@@ -6515,39 +3312,65 @@ static void ssl_calc_finished_tls_sha256(
sha256.state, sizeof( sha256.state ) );
#endif
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
-
mbedtls_sha256_finish_ret( &sha256, padbuf );
+ mbedtls_sha256_free( &sha256 );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 32, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha256_free( &sha256 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
}
#endif /* MBEDTLS_SHA256_C */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
static void ssl_calc_finished_tls_sha384(
mbedtls_ssl_context *ssl, unsigned char *buf, int from )
{
int len = 12;
const char *sender;
- mbedtls_sha512_context sha512;
unsigned char padbuf[48];
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ size_t hash_size;
+ psa_hash_operation_t sha384_psa = PSA_HASH_OPERATION_INIT;
+ psa_status_t status;
+#else
+ mbedtls_sha512_context sha512;
+#endif
mbedtls_ssl_session *session = ssl->session_negotiate;
if( !session )
session = ssl->session;
+ sender = ( from == MBEDTLS_SSL_IS_CLIENT )
+ ? "client finished"
+ : "server finished";
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ sha384_psa = psa_hash_operation_init();
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc PSA finished tls sha384" ) );
+
+ status = psa_hash_clone( &ssl->handshake->fin_sha384_psa, &sha384_psa );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash clone failed" ) );
+ return;
+ }
+
+ status = psa_hash_finish( &sha384_psa, padbuf, sizeof( padbuf ), &hash_size );
+ if( status != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "PSA hash finish failed" ) );
+ return;
+ }
+ MBEDTLS_SSL_DEBUG_BUF( 3, "PSA calculated padbuf", padbuf, 48 );
+#else
mbedtls_sha512_init( &sha512 );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) );
@@ -6564,10 +3387,6 @@ static void ssl_calc_finished_tls_sha384(
MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *)
sha512.state, sizeof( sha512.state ) );
#endif
-
- sender = ( from == MBEDTLS_SSL_IS_CLIENT )
- ? "client finished"
- : "server finished";
/* mbedtls_sha512_finish_ret's output parameter is declared as a
* 64-byte buffer, but sice we're using SHA-384, we know that the
* output fits in 48 bytes. This is correct C, but GCC 11.1 warns
@@ -6582,21 +3401,22 @@ static void ssl_calc_finished_tls_sha384(
#pragma GCC diagnostic pop
#endif
+ mbedtls_sha512_free( &sha512 );
+#endif
+
ssl->handshake->tls_prf( session->master, 48, sender,
padbuf, 48, buf, len );
MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len );
- mbedtls_sha512_free( &sha512 );
-
mbedtls_platform_zeroize( padbuf, sizeof( padbuf ) );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) );
}
-#endif /* MBEDTLS_SHA512_C */
+#endif /* MBEDTLS_SHA512_C && !MBEDTLS_SHA512_NO_SHA384 */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
-static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
+void mbedtls_ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) );
@@ -6668,7 +3488,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
ssl->handshake->flight != NULL )
{
/* Cancel handshake timer */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
/* Keep last flight around in case we need to resend it:
* we need the handshake and transform structures for that */
@@ -6676,7 +3496,7 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl )
}
else
#endif
- ssl_handshake_wrapup_free_hs_transform( ssl );
+ mbedtls_ssl_handshake_wrapup_free_hs_transform( ssl );
ssl->state++;
@@ -6689,7 +3509,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) );
- ssl_update_out_pointers( ssl, ssl->transform_negotiate );
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform_negotiate );
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint );
@@ -6809,7 +3629,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned int hash_len;
unsigned char buf[SSL_MAX_HASH_LEN];
@@ -6850,7 +3670,7 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl )
goto exit;
}
- if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
+ if( mbedtls_ct_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ),
buf, hash_len ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) );
@@ -6904,19 +3724,29 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#endif
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha256_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha256_psa, PSA_ALG_SHA_256 );
+#else
mbedtls_sha256_init( &handshake->fin_sha256 );
mbedtls_sha256_starts_ret( &handshake->fin_sha256, 0 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ handshake->fin_sha384_psa = psa_hash_operation_init();
+ psa_hash_setup( &handshake->fin_sha384_psa, PSA_ALG_SHA_384 );
+#else
mbedtls_sha512_init( &handshake->fin_sha512 );
mbedtls_sha512_starts_ret( &handshake->fin_sha512, 1 );
#endif
+#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
handshake->update_checksum = ssl_update_checksum_start;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs );
#endif
@@ -6934,24 +3764,31 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#endif
#endif
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
mbedtls_x509_crt_restart_init( &handshake->ecrs_ctx );
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
#endif
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_init( &handshake->peer_pubkey );
+#endif
}
-static void ssl_transform_init( mbedtls_ssl_transform *transform )
+void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform )
{
memset( transform, 0, sizeof(mbedtls_ssl_transform) );
mbedtls_cipher_init( &transform->cipher_ctx_enc );
mbedtls_cipher_init( &transform->cipher_ctx_dec );
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
mbedtls_md_init( &transform->md_ctx_enc );
mbedtls_md_init( &transform->md_ctx_dec );
+#endif
}
void mbedtls_ssl_session_init( mbedtls_ssl_session *session )
@@ -6987,6 +3824,12 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
{
ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
}
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too small - reallocate */
+
+ handle_buffer_resizing( ssl, 0, MBEDTLS_SSL_IN_BUFFER_LEN,
+ MBEDTLS_SSL_OUT_BUFFER_LEN );
+#endif
/* All pointers should exist and can be directly freed without issue */
if( ssl->handshake == NULL ||
@@ -7008,7 +3851,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
/* Initialize structures */
mbedtls_ssl_session_init( ssl->session_negotiate );
- ssl_transform_init( ssl->transform_negotiate );
+ mbedtls_ssl_transform_init( ssl->transform_negotiate );
ssl_handshake_params_init( ssl->handshake );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -7021,7 +3864,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
else
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
}
#endif
@@ -7057,78 +3900,6 @@ static int ssl_cookie_check_dummy( void *ctx,
}
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */
-/* Once ssl->out_hdr as the address of the beginning of the
- * next outgoing record is set, deduce the other pointers.
- *
- * Note: For TLS, we save the implicit record sequence number
- * (entering MAC computation) in the 8 bytes before ssl->out_hdr,
- * and the caller has to make sure there's space for this.
- */
-
-static void ssl_update_out_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_ctr = ssl->out_hdr + 3;
- ssl->out_len = ssl->out_hdr + 11;
- ssl->out_iv = ssl->out_hdr + 13;
- }
- else
-#endif
- {
- ssl->out_ctr = ssl->out_hdr - 8;
- ssl->out_len = ssl->out_hdr + 3;
- ssl->out_iv = ssl->out_hdr + 5;
- }
-
- /* Adjust out_msg to make space for explicit IV, if used. */
- if( transform != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->out_msg = ssl->out_iv + transform->ivlen - transform->fixed_ivlen;
- }
- else
- ssl->out_msg = ssl->out_iv;
-}
-
-/* Once ssl->in_hdr as the address of the beginning of the
- * next incoming record is set, deduce the other pointers.
- *
- * Note: For TLS, we save the implicit record sequence number
- * (entering MAC computation) in the 8 bytes before ssl->in_hdr,
- * and the caller has to make sure there's space for this.
- */
-
-static void ssl_update_in_pointers( mbedtls_ssl_context *ssl,
- mbedtls_ssl_transform *transform )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->in_ctr = ssl->in_hdr + 3;
- ssl->in_len = ssl->in_hdr + 11;
- ssl->in_iv = ssl->in_hdr + 13;
- }
- else
-#endif
- {
- ssl->in_ctr = ssl->in_hdr - 8;
- ssl->in_len = ssl->in_hdr + 3;
- ssl->in_iv = ssl->in_hdr + 5;
- }
-
- /* Offset in_msg from in_iv to allow space for explicit IV, if used. */
- if( transform != NULL &&
- ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- {
- ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen;
- }
- else
- ssl->in_msg = ssl->in_iv;
-}
-
/*
* Initialize an SSL context
*/
@@ -7141,31 +3912,12 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl )
* Setup an SSL context
*/
-static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl )
-{
- /* Set the incoming and outgoing record pointers. */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ssl->out_hdr = ssl->out_buf;
- ssl->in_hdr = ssl->in_buf;
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
- {
- ssl->out_hdr = ssl->out_buf + 8;
- ssl->in_hdr = ssl->in_buf + 8;
- }
-
- /* Derive other internal pointers. */
- ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
- ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ );
-}
-
int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
ssl->conf = conf;
@@ -7176,23 +3928,33 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
/* Set to NULL in case of an error condition */
ssl->out_buf = NULL;
- ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = in_buf_len;
+#endif
+ ssl->in_buf = mbedtls_calloc( 1, in_buf_len );
if( ssl->in_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", in_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
- ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->out_buf_len = out_buf_len;
+#endif
+ ssl->out_buf = mbedtls_calloc( 1, out_buf_len );
if( ssl->out_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%" MBEDTLS_PRINTF_SIZET " bytes) failed", out_buf_len ) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
- ssl_reset_in_out_pointers( ssl );
+ mbedtls_ssl_reset_in_out_pointers( ssl );
+
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ memset( &ssl->dtls_srtp_info, 0, sizeof(ssl->dtls_srtp_info) );
+#endif
if( ( ret = ssl_handshake_init( ssl ) ) != 0 )
goto error;
@@ -7205,6 +3967,10 @@ error:
ssl->conf = NULL;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = 0;
+ ssl->out_buf_len = 0;
+#endif
ssl->in_buf = NULL;
ssl->out_buf = NULL;
@@ -7230,9 +3996,16 @@ error:
* If partial is non-zero, keep data in the input buffer and client ID.
* (Use when a DTLS client reconnects from the same port.)
*/
-static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
+int mbedtls_ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
!defined(MBEDTLS_SSL_SRV_C)
@@ -7242,7 +4015,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->state = MBEDTLS_SSL_HELLO_REQUEST;
/* Cancel any possibly running timer */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
#if defined(MBEDTLS_SSL_RENEGOTIATION)
ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE;
@@ -7255,7 +4028,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION;
ssl->in_offt = NULL;
- ssl_reset_in_out_pointers( ssl );
+ mbedtls_ssl_reset_in_out_pointers( ssl );
ssl->in_msgtype = 0;
ssl->in_msglen = 0;
@@ -7264,7 +4037,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->in_epoch = 0;
#endif
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- ssl_dtls_replay_reset( ssl );
+ mbedtls_ssl_dtls_replay_reset( ssl );
#endif
ssl->in_hslen = 0;
@@ -7288,14 +4061,14 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->session_in = NULL;
ssl->session_out = NULL;
- memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
+ memset( ssl->out_buf, 0, out_buf_len );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 )
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
{
ssl->in_left = 0;
- memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
+ memset( ssl->in_buf, 0, in_buf_len );
}
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@@ -7351,7 +4124,7 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
*/
int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl )
{
- return( ssl_session_reset_int( ssl, 0 ) );
+ return( mbedtls_ssl_session_reset_int( ssl, 0 ) );
}
/*
@@ -7462,7 +4235,7 @@ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
ssl->f_get_timer = f_get_timer;
/* Make sure we start with no timer running */
- ssl_set_timer( ssl, 0 );
+ mbedtls_ssl_set_timer( ssl, 0 );
}
#if defined(MBEDTLS_SSL_SRV_C)
@@ -7480,7 +4253,7 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf,
#if defined(MBEDTLS_SSL_CLI_C)
int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ssl == NULL ||
session == NULL ||
@@ -7490,7 +4263,8 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 )
+ if( ( ret = mbedtls_ssl_session_copy( ssl->session_negotiate,
+ session ) ) != 0 )
return( ret );
ssl->handshake->resume = 1;
@@ -7572,7 +4346,29 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
{
conf->ca_chain = ca_chain;
conf->ca_crl = ca_crl;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
+ * cannot be used together. */
+ conf->f_ca_cb = NULL;
+ conf->p_ca_cb = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+}
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+void mbedtls_ssl_conf_ca_cb( mbedtls_ssl_config *conf,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb )
+{
+ conf->f_ca_cb = f_ca_cb;
+ conf->p_ca_cb = p_ca_cb;
+
+ /* mbedtls_ssl_conf_ca_chain() and mbedtls_ssl_conf_ca_cb()
+ * cannot be used together. */
+ conf->ca_chain = NULL;
+ conf->ca_crl = NULL;
}
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
@@ -7599,6 +4395,16 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ ssl->f_vrfy = f_vrfy;
+ ssl->p_vrfy = p_vrfy;
+}
+#endif
+
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/*
* Set EC J-PAKE password for current handshake
@@ -7625,24 +4431,24 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
-int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
- const unsigned char *psk, size_t psk_len,
- const unsigned char *psk_identity, size_t psk_identity_len )
-{
- if( psk == NULL || psk_identity == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-
- if( psk_len > MBEDTLS_PSK_MAX_LEN )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
- /* Identity len will be encoded on two bytes */
- if( ( psk_identity_len >> 16 ) != 0 ||
- psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
+static void ssl_conf_remove_psk( mbedtls_ssl_config *conf )
+{
+ /* Remove reference to existing PSK, if any. */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( conf->psk_opaque ) )
{
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ /* The maintenance of the PSK key slot is the
+ * user's responsibility. */
+ conf->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
}
-
+ /* This and the following branch should never
+ * be taken simultaenously as we maintain the
+ * invariant that raw and opaque PSKs are never
+ * configured simultaneously. As a safeguard,
+ * though, `else` is omitted here. */
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( conf->psk != NULL )
{
mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@@ -7651,41 +4457,80 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
conf->psk = NULL;
conf->psk_len = 0;
}
+
+ /* Remove reference to PSK identity, if any. */
if( conf->psk_identity != NULL )
{
mbedtls_free( conf->psk_identity );
conf->psk_identity = NULL;
conf->psk_identity_len = 0;
}
+}
- if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
- ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
+/* This function assumes that PSK identity in the SSL config is unset.
+ * It checks that the provided identity is well-formed and attempts
+ * to make a copy of it in the SSL config.
+ * On failure, the PSK identity in the config remains unset. */
+static int ssl_conf_set_psk_identity( mbedtls_ssl_config *conf,
+ unsigned char const *psk_identity,
+ size_t psk_identity_len )
+{
+ /* Identity len will be encoded on two bytes */
+ if( psk_identity == NULL ||
+ ( psk_identity_len >> 16 ) != 0 ||
+ psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
- mbedtls_free( conf->psk );
- mbedtls_free( conf->psk_identity );
- conf->psk = NULL;
- conf->psk_identity = NULL;
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- conf->psk_len = psk_len;
- conf->psk_identity_len = psk_identity_len;
+ conf->psk_identity = mbedtls_calloc( 1, psk_identity_len );
+ if( conf->psk_identity == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- memcpy( conf->psk, psk, conf->psk_len );
+ conf->psk_identity_len = psk_identity_len;
memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len );
return( 0 );
}
-int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
- const unsigned char *psk, size_t psk_len )
+int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
+ const unsigned char *psk, size_t psk_len,
+ const unsigned char *psk_identity, size_t psk_identity_len )
{
- if( psk == NULL || ssl->handshake == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Remove opaque/raw PSK + PSK Identity */
+ ssl_conf_remove_psk( conf );
+ /* Check and set raw PSK */
+ if( psk == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( psk_len == 0 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( psk_len > MBEDTLS_PSK_MAX_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ conf->psk_len = psk_len;
+ memcpy( conf->psk, psk, conf->psk_len );
+
+ /* Check and set PSK Identity */
+ ret = ssl_conf_set_psk_identity( conf, psk_identity, psk_identity_len );
+ if( ret != 0 )
+ ssl_conf_remove_psk( conf );
+
+ return( ret );
+}
+
+static void ssl_remove_psk( mbedtls_ssl_context *ssl )
+{
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( ! mbedtls_svc_key_id_is_null( ssl->handshake->psk_opaque ) )
+ {
+ ssl->handshake->psk_opaque = MBEDTLS_SVC_KEY_ID_INIT;
+ }
+ else
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
if( ssl->handshake->psk != NULL )
{
mbedtls_platform_zeroize( ssl->handshake->psk,
@@ -7693,6 +4538,18 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk_len = 0;
}
+}
+
+int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
+ const unsigned char *psk, size_t psk_len )
+{
+ if( psk == NULL || ssl->handshake == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( psk_len > MBEDTLS_PSK_MAX_LEN )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_remove_psk( ssl );
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
@@ -7703,6 +4560,43 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
return( 0 );
}
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_conf_psk_opaque( mbedtls_ssl_config *conf,
+ psa_key_id_t psk,
+ const unsigned char *psk_identity,
+ size_t psk_identity_len )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ /* Clear opaque/raw PSK + PSK Identity, if present. */
+ ssl_conf_remove_psk( conf );
+
+ /* Check and set opaque PSK */
+ if( mbedtls_svc_key_id_is_null( psk ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ conf->psk_opaque = psk;
+
+ /* Check and set PSK Identity */
+ ret = ssl_conf_set_psk_identity( conf, psk_identity,
+ psk_identity_len );
+ if( ret != 0 )
+ ssl_conf_remove_psk( conf );
+
+ return( ret );
+}
+
+int mbedtls_ssl_set_hs_psk_opaque( mbedtls_ssl_context *ssl,
+ psa_key_id_t psk )
+{
+ if( ( mbedtls_svc_key_id_is_null( psk ) ) ||
+ ( ssl->handshake == NULL ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_remove_psk( ssl );
+ ssl->handshake->psk_opaque = psk;
+ return( 0 );
+}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *,
size_t),
@@ -7711,14 +4605,14 @@ void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf,
conf->f_psk = f_psk;
conf->p_psk = p_psk;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED */
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 ||
( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 )
@@ -7736,7 +4630,7 @@ int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
const unsigned char *dhm_P, size_t P_len,
const unsigned char *dhm_G, size_t G_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_read_binary( &conf->dhm_P, dhm_P, P_len ) ) != 0 ||
( ret = mbedtls_mpi_read_binary( &conf->dhm_G, dhm_G, G_len ) ) != 0 )
@@ -7751,7 +4645,7 @@ int mbedtls_ssl_conf_dh_param_bin( mbedtls_ssl_config *conf,
int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 ||
( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 )
@@ -7776,7 +4670,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
}
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Set allowed/preferred hashes for handshake signatures
*/
@@ -7785,7 +4679,7 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
{
conf->sig_hashes = hashes;
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_ECP_C)
/*
@@ -7889,6 +4783,86 @@ const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl )
}
#endif /* MBEDTLS_SSL_ALPN */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+void mbedtls_ssl_conf_srtp_mki_value_supported( mbedtls_ssl_config *conf,
+ int support_mki_value )
+{
+ conf->dtls_srtp_mki_support = support_mki_value;
+}
+
+int mbedtls_ssl_dtls_srtp_set_mki_value( mbedtls_ssl_context *ssl,
+ unsigned char *mki_value,
+ uint16_t mki_len )
+{
+ if( mki_len > MBEDTLS_TLS_SRTP_MAX_MKI_LENGTH )
+ {
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ if( ssl->conf->dtls_srtp_mki_support == MBEDTLS_SSL_DTLS_SRTP_MKI_UNSUPPORTED )
+ {
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
+
+ memcpy( ssl->dtls_srtp_info.mki_value, mki_value, mki_len );
+ ssl->dtls_srtp_info.mki_len = mki_len;
+ return( 0 );
+}
+
+int mbedtls_ssl_conf_dtls_srtp_protection_profiles( mbedtls_ssl_config *conf,
+ const mbedtls_ssl_srtp_profile *profiles )
+{
+ const mbedtls_ssl_srtp_profile *p;
+ size_t list_size = 0;
+
+ /* check the profiles list: all entry must be valid,
+ * its size cannot be more than the total number of supported profiles, currently 4 */
+ for( p = profiles; *p != MBEDTLS_TLS_SRTP_UNSET &&
+ list_size <= MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH;
+ p++ )
+ {
+ if( mbedtls_ssl_check_srtp_profile_value( *p ) != MBEDTLS_TLS_SRTP_UNSET )
+ {
+ list_size++;
+ }
+ else
+ {
+ /* unsupported value, stop parsing and set the size to an error value */
+ list_size = MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH + 1;
+ }
+ }
+
+ if( list_size > MBEDTLS_TLS_SRTP_MAX_PROFILE_LIST_LENGTH )
+ {
+ conf->dtls_srtp_profile_list = NULL;
+ conf->dtls_srtp_profile_list_len = 0;
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+
+ conf->dtls_srtp_profile_list = profiles;
+ conf->dtls_srtp_profile_list_len = list_size;
+
+ return( 0 );
+}
+
+void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ssl,
+ mbedtls_dtls_srtp_info *dtls_srtp_info )
+{
+ dtls_srtp_info->chosen_dtls_srtp_profile = ssl->dtls_srtp_info.chosen_dtls_srtp_profile;
+ /* do not copy the mki value if there is no chosen profile */
+ if( dtls_srtp_info->chosen_dtls_srtp_profile == MBEDTLS_TLS_SRTP_UNSET )
+ {
+ dtls_srtp_info->mki_len = 0;
+ }
+ else
+ {
+ dtls_srtp_info->mki_len = ssl->dtls_srtp_info.mki_len;
+ memcpy( dtls_srtp_info->mki_value, ssl->dtls_srtp_info.mki_value,
+ ssl->dtls_srtp_info.mki_len );
+ }
+}
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
+
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor )
{
conf->max_major_ver = major;
@@ -8018,6 +4992,14 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
conf->f_export_keys = f_export_keys;
conf->p_export_keys = p_export_keys;
}
+
+void mbedtls_ssl_conf_export_keys_ext_cb( mbedtls_ssl_config *conf,
+ mbedtls_ssl_export_keys_ext_t *f_export_keys_ext,
+ void *p_export_keys )
+{
+ conf->f_export_keys_ext = f_export_keys_ext;
+ conf->p_export_keys = p_export_keys;
+}
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -8060,66 +5042,6 @@ void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
/*
* SSL get accessors
*/
-size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl )
-{
- return( ssl->in_offt == NULL ? 0 : ssl->in_msglen );
-}
-
-int mbedtls_ssl_check_pending( const mbedtls_ssl_context *ssl )
-{
- /*
- * Case A: We're currently holding back
- * a message for further processing.
- */
-
- if( ssl->keep_current_message == 1 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: record held back for processing" ) );
- return( 1 );
- }
-
- /*
- * Case B: Further records are pending in the current datagram.
- */
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->in_left > ssl->next_record_offset )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
- return( 1 );
- }
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
- /*
- * Case C: A handshake message is being processed.
- */
-
- if( ssl->in_hslen > 0 && ssl->in_hslen < ssl->in_msglen )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more handshake messages within current record" ) );
- return( 1 );
- }
-
- /*
- * Case D: An application data message is being processed
- */
- if( ssl->in_offt != NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: application data record is being processed" ) );
- return( 1 );
- }
-
- /*
- * In all other cases, the rest of the message can be dropped.
- * As in ssl_get_next_record, this needs to be adapted if
- * we implement support for multiple alerts in single records.
- */
-
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: nothing pending" ) );
- return( 0 );
-}
-
uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl )
{
if( ssl->session != NULL )
@@ -8177,61 +5099,43 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
}
}
-int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl )
{
- size_t transform_expansion = 0;
- const mbedtls_ssl_transform *transform = ssl->transform_out;
- unsigned block_size;
-
- if( transform == NULL )
- return( (int) mbedtls_ssl_hdr_len( ssl ) );
-
-#if defined(MBEDTLS_ZLIB_SUPPORT)
- if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
-#endif
+ size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
+ size_t read_mfl;
- switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+ /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE )
{
- case MBEDTLS_MODE_GCM:
- case MBEDTLS_MODE_CCM:
- case MBEDTLS_MODE_CHACHAPOLY:
- case MBEDTLS_MODE_STREAM:
- transform_expansion = transform->minlen;
- break;
-
- case MBEDTLS_MODE_CBC:
-
- block_size = mbedtls_cipher_get_block_size(
- &transform->cipher_ctx_enc );
-
- /* Expansion due to the addition of the MAC. */
- transform_expansion += transform->maclen;
-
- /* Expansion due to the addition of CBC padding;
- * Theoretically up to 256 bytes, but we never use
- * more than the block size of the underlying cipher. */
- transform_expansion += block_size;
-
- /* For TLS 1.1 or higher, an explicit IV is added
- * after the record header. */
-#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 )
- transform_expansion += block_size;
-#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
+ return ssl_mfl_code_to_length( ssl->conf->mfl_code );
+ }
- break;
+ /* Check if a smaller max length was negotiated */
+ if( ssl->session_out != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
+ }
- default:
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ // During a handshake, use the value being negotiated
+ if( ssl->session_negotiate != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
}
- return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) );
+ return( max_len );
}
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl )
{
size_t max_len;
@@ -8256,10 +5160,17 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
return( max_len );
}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+{
+ return mbedtls_ssl_get_output_max_frag_len( ssl );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
-static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
+size_t mbedtls_ssl_get_current_mtu( const mbedtls_ssl_context *ssl )
{
/* Return unlimited mtu for client hello messages to avoid fragmentation. */
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
@@ -8288,16 +5199,16 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
if( max_len > mfl )
max_len = mfl;
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl_get_current_mtu( ssl ) != 0 )
+ if( mbedtls_ssl_get_current_mtu( ssl ) != 0 )
{
- const size_t mtu = ssl_get_current_mtu( ssl );
+ const size_t mtu = mbedtls_ssl_get_current_mtu( ssl );
const int ret = mbedtls_ssl_get_record_expansion( ssl );
const size_t overhead = (size_t) ret;
@@ -8329,12 +5240,17 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss
if( ssl == NULL || ssl->session == NULL )
return( NULL );
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
return( ssl->session->peer_cert );
+#else
+ return( NULL );
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_CLI_C)
-int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst )
+int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl,
+ mbedtls_ssl_session *dst )
{
if( ssl == NULL ||
dst == NULL ||
@@ -8344,10 +5260,567 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- return( ssl_session_copy( dst, ssl->session ) );
+ return( mbedtls_ssl_session_copy( dst, ssl->session ) );
}
#endif /* MBEDTLS_SSL_CLI_C */
+const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_context *ssl )
+{
+ if( ssl == NULL )
+ return( NULL );
+
+ return( ssl->session );
+}
+
+/*
+ * Define ticket header determining Mbed TLS version
+ * and structure of the ticket.
+ */
+
+/*
+ * Define bitflag determining compile-time settings influencing
+ * structure of serialized SSL sessions.
+ */
+
+#if defined(MBEDTLS_HAVE_TIME)
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME 0
+#endif /* MBEDTLS_HAVE_TIME */
+
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT 0
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+#if defined(MBEDTLS_SSL_CLI_C) && defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET 0
+#endif /* MBEDTLS_SSL_CLI_C && MBEDTLS_SSL_SESSION_TICKETS */
+
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL 0
+#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC 0
+#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM 0
+#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 1
+#else
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET 0
+#endif /* MBEDTLS_SSL_SESSION_TICKETS */
+
+#define SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT 0
+#define SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT 1
+#define SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT 2
+#define SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT 3
+#define SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT 4
+#define SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT 5
+#define SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT 6
+
+#define SSL_SERIALIZED_SESSION_CONFIG_BITFLAG \
+ ( (uint16_t) ( \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TIME << SSL_SERIALIZED_SESSION_CONFIG_TIME_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_CRT << SSL_SERIALIZED_SESSION_CONFIG_CRT_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET << SSL_SERIALIZED_SESSION_CONFIG_CLIENT_TICKET_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_MFL << SSL_SERIALIZED_SESSION_CONFIG_MFL_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC << SSL_SERIALIZED_SESSION_CONFIG_TRUNC_HMAC_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_ETM << SSL_SERIALIZED_SESSION_CONFIG_ETM_BIT ) | \
+ ( SSL_SERIALIZED_SESSION_CONFIG_TICKET << SSL_SERIALIZED_SESSION_CONFIG_TICKET_BIT ) ) )
+
+static unsigned char ssl_serialized_session_header[] = {
+ MBEDTLS_VERSION_MAJOR,
+ MBEDTLS_VERSION_MINOR,
+ MBEDTLS_VERSION_PATCH,
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+};
+
+/*
+ * Serialize a session in the following format:
+ * (in the presentation language of TLS, RFC 8446 section 3)
+ *
+ * opaque mbedtls_version[3]; // major, minor, patch
+ * opaque session_format[2]; // version-specific 16-bit field determining
+ * // the format of the remaining
+ * // serialized data.
+ *
+ * Note: When updating the format, remember to keep
+ * these version+format bytes.
+ *
+ * // In this version, `session_format` determines
+ * // the setting of those compile-time
+ * // configuration options which influence
+ * // the structure of mbedtls_ssl_session.
+ * uint64 start_time;
+ * uint8 ciphersuite[2]; // defined by the standard
+ * uint8 compression; // 0 or 1
+ * uint8 session_id_len; // at most 32
+ * opaque session_id[32];
+ * opaque master[48]; // fixed length in the standard
+ * uint32 verify_result;
+ * opaque peer_cert<0..2^24-1>; // length 0 means no peer cert
+ * opaque ticket<0..2^24-1>; // length 0 means no ticket
+ * uint32 ticket_lifetime;
+ * uint8 mfl_code; // up to 255 according to standard
+ * uint8 trunc_hmac; // 0 or 1
+ * uint8 encrypt_then_mac; // 0 or 1
+ *
+ * The order is the same as in the definition of the structure, except
+ * verify_result is put before peer_cert so that all mandatory fields come
+ * together in one block.
+ */
+static int ssl_session_save( const mbedtls_ssl_session *session,
+ unsigned char omit_header,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+
+ if( !omit_header )
+ {
+ /*
+ * Add version identifier
+ */
+
+ used += sizeof( ssl_serialized_session_header );
+
+ if( used <= buf_len )
+ {
+ memcpy( p, ssl_serialized_session_header,
+ sizeof( ssl_serialized_session_header ) );
+ p += sizeof( ssl_serialized_session_header );
+ }
+ }
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ used += 8;
+
+ if( used <= buf_len )
+ {
+ start = (uint64_t) session->start;
+
+ MBEDTLS_PUT_UINT64_BE( start, p, 0 );
+ p += 8;
+ }
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ used += 2 /* ciphersuite */
+ + 1 /* compression */
+ + 1 /* id_len */
+ + sizeof( session->id )
+ + sizeof( session->master )
+ + 4; /* verify_result */
+
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT16_BE( session->ciphersuite, p, 0 );
+ p += 2;
+
+ *p++ = MBEDTLS_BYTE_0( session->compression );
+
+ *p++ = MBEDTLS_BYTE_0( session->id_len );
+ memcpy( p, session->id, 32 );
+ p += 32;
+
+ memcpy( p, session->master, 48 );
+ p += 48;
+
+ MBEDTLS_PUT_UINT32_BE( session->verify_result, p, 0 );
+ p += 4;
+ }
+
+ /*
+ * Peer's end-entity certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( session->peer_cert == NULL )
+ cert_len = 0;
+ else
+ cert_len = session->peer_cert->raw.len;
+
+ used += 3 + cert_len;
+
+ if( used <= buf_len )
+ {
+ *p++ = MBEDTLS_BYTE_2( cert_len );
+ *p++ = MBEDTLS_BYTE_1( cert_len );
+ *p++ = MBEDTLS_BYTE_0( cert_len );
+
+ if( session->peer_cert != NULL )
+ {
+ memcpy( p, session->peer_cert->raw.p, cert_len );
+ p += cert_len;
+ }
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ if( session->peer_cert_digest != NULL )
+ {
+ used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
+ if( used <= buf_len )
+ {
+ *p++ = (unsigned char) session->peer_cert_digest_type;
+ *p++ = (unsigned char) session->peer_cert_digest_len;
+ memcpy( p, session->peer_cert_digest,
+ session->peer_cert_digest_len );
+ p += session->peer_cert_digest_len;
+ }
+ }
+ else
+ {
+ used += 2;
+ if( used <= buf_len )
+ {
+ *p++ = (unsigned char) MBEDTLS_MD_NONE;
+ *p++ = 0;
+ }
+ }
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket if any, plus associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
+
+ if( used <= buf_len )
+ {
+ *p++ = MBEDTLS_BYTE_2( session->ticket_len );
+ *p++ = MBEDTLS_BYTE_1( session->ticket_len );
+ *p++ = MBEDTLS_BYTE_0( session->ticket_len );
+
+ if( session->ticket != NULL )
+ {
+ memcpy( p, session->ticket, session->ticket_len );
+ p += session->ticket_len;
+ }
+
+ MBEDTLS_PUT_UINT32_BE( session->ticket_lifetime, p, 0 );
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = session->mfl_code;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = (unsigned char)( ( session->trunc_hmac ) & 0xFF );
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ used += 1;
+
+ if( used <= buf_len )
+ *p++ = MBEDTLS_BYTE_0( session->encrypt_then_mac );
+#endif
+
+ /* Done */
+ *olen = used;
+
+ if( used > buf_len )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ return( 0 );
+}
+
+/*
+ * Public wrapper for ssl_session_save()
+ */
+int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ return( ssl_session_save( session, 0, buf, buf_len, olen ) );
+}
+
+/*
+ * Deserialize session, see mbedtls_ssl_session_save() for format.
+ *
+ * This internal version is wrapped by a public function that cleans up in
+ * case of error, and has an extra option omit_header.
+ */
+static int ssl_session_load( mbedtls_ssl_session *session,
+ unsigned char omit_header,
+ const unsigned char *buf,
+ size_t len )
+{
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+#if defined(MBEDTLS_HAVE_TIME)
+ uint64_t start;
+#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ size_t cert_len;
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ if( !omit_header )
+ {
+ /*
+ * Check version identifier
+ */
+
+ if( (size_t)( end - p ) < sizeof( ssl_serialized_session_header ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( memcmp( p, ssl_serialized_session_header,
+ sizeof( ssl_serialized_session_header ) ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
+ }
+ p += sizeof( ssl_serialized_session_header );
+ }
+
+ /*
+ * Time
+ */
+#if defined(MBEDTLS_HAVE_TIME)
+ if( 8 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ start = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+
+ session->start = (time_t) start;
+#endif /* MBEDTLS_HAVE_TIME */
+
+ /*
+ * Basic mandatory fields
+ */
+ if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ciphersuite = ( p[0] << 8 ) | p[1];
+ p += 2;
+
+ session->compression = *p++;
+
+ session->id_len = *p++;
+ memcpy( session->id, p, 32 );
+ p += 32;
+
+ memcpy( session->master, p, 48 );
+ p += 48;
+
+ session->verify_result = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+
+ /* Immediately clear invalid pointer values that have been read, in case
+ * we exit early before we replaced them with valid ones. */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ session->peer_cert = NULL;
+#else
+ session->peer_cert_digest = NULL;
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ session->ticket = NULL;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Peer certificate
+ */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ /* Deserialize CRT from the end of the ticket. */
+ if( 3 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+ p += 3;
+
+ if( cert_len != 0 )
+ {
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+
+ if( cert_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+
+ if( session->peer_cert == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ mbedtls_x509_crt_init( session->peer_cert );
+
+ if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert,
+ p, cert_len ) ) != 0 )
+ {
+ mbedtls_x509_crt_free( session->peer_cert );
+ mbedtls_free( session->peer_cert );
+ session->peer_cert = NULL;
+ return( ret );
+ }
+
+ p += cert_len;
+ }
+#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+ /* Deserialize CRT digest from the end of the ticket. */
+ if( 2 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
+ session->peer_cert_digest_len = (size_t) *p++;
+
+ if( session->peer_cert_digest_len != 0 )
+ {
+ const mbedtls_md_info_t *md_info =
+ mbedtls_md_info_from_type( session->peer_cert_digest_type );
+ if( md_info == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( session->peer_cert_digest_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->peer_cert_digest =
+ mbedtls_calloc( 1, session->peer_cert_digest_len );
+ if( session->peer_cert_digest == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( session->peer_cert_digest, p,
+ session->peer_cert_digest_len );
+ p += session->peer_cert_digest_len;
+ }
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
+
+ /*
+ * Session ticket and associated data
+ */
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ if( 3 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
+ p += 3;
+
+ if( session->ticket_len != 0 )
+ {
+ if( session->ticket_len > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket = mbedtls_calloc( 1, session->ticket_len );
+ if( session->ticket == NULL )
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+
+ memcpy( session->ticket, p, session->ticket_len );
+ p += session->ticket_len;
+ }
+
+ if( 4 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
+
+ /*
+ * Misc extension-related info
+ */
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->mfl_code = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->trunc_hmac = *p++;
+#endif
+
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ if( 1 > (size_t)( end - p ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ session->encrypt_then_mac = *p++;
+#endif
+
+ /* Done, should have consumed entire buffer */
+ if( p != end )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ return( 0 );
+}
+
+/*
+ * Deserialize session: public wrapper for error cleaning
+ */
+int mbedtls_ssl_session_load( mbedtls_ssl_session *session,
+ const unsigned char *buf,
+ size_t len )
+{
+ int ret = ssl_session_load( session, 0, buf, len );
+
+ if( ret != 0 )
+ mbedtls_ssl_session_free( session );
+
+ return( ret );
+}
+
/*
* Perform a single step of the SSL handshake
*/
@@ -8377,11 +5850,24 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
{
int ret = 0;
+ /* Sanity checks */
+
if( ssl == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ ( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use "
+ "mbedtls_ssl_set_timer_cb() for DTLS" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
+ /* Main handshake loop */
while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
ret = mbedtls_ssl_handshake_step( ssl );
@@ -8402,7 +5888,7 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl )
*/
static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) );
@@ -8431,9 +5917,9 @@ static int ssl_write_hello_request( mbedtls_ssl_context *ssl )
* If the handshake doesn't complete due to waiting for I/O, it will continue
* during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively.
*/
-static int ssl_start_renegotiation( mbedtls_ssl_context *ssl )
+int mbedtls_ssl_start_renegotiation( mbedtls_ssl_context *ssl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) );
@@ -8505,9 +5991,9 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 )
+ if( ( ret = mbedtls_ssl_start_renegotiation( ssl ) ) != 0 )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_start_renegotiation", ret );
return( ret );
}
}
@@ -8523,708 +6009,785 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl )
return( ret );
}
+#endif /* MBEDTLS_SSL_RENEGOTIATION */
-/*
- * Check record counters and renegotiate if they're above the limit.
- */
-static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl )
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
{
- size_t ep_len = ssl_ep_len( ssl );
- int in_ctr_cmp;
- int out_ctr_cmp;
+ mbedtls_ssl_key_cert *cur = key_cert, *next;
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ||
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ||
- ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ while( cur != NULL )
{
- return( 0 );
+ next = cur->next;
+ mbedtls_free( cur );
+ cur = next;
}
+}
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
- in_ctr_cmp = memcmp( ssl->in_ctr + ep_len,
- ssl->conf->renego_period + ep_len, 8 - ep_len );
- out_ctr_cmp = memcmp( ssl->cur_out_ctr + ep_len,
- ssl->conf->renego_period + ep_len, 8 - ep_len );
+void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
+{
+ mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+
+ if( handshake == NULL )
+ return;
- if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 )
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
{
- return( 0 );
+ ssl->conf->f_async_cancel( ssl );
+ handshake->async_in_progress = 0;
}
+#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) );
- return( mbedtls_ssl_renegotiate( ssl ) );
-}
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
-
-/*
- * Receive application data decrypted from the SSL layer
- */
-int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
-{
- int ret;
- size_t n;
+#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1)
+ mbedtls_md5_free( &handshake->fin_md5 );
+ mbedtls_sha1_free( &handshake->fin_sha1 );
+#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
+#if defined(MBEDTLS_SHA256_C)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha256_psa );
+#else
+ mbedtls_sha256_free( &handshake->fin_sha256 );
+#endif
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_abort( &handshake->fin_sha384_psa );
+#else
+ mbedtls_sha512_free( &handshake->fin_sha512 );
+#endif
+#endif
+#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
- if( ssl == NULL || ssl->conf == NULL )
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+#if defined(MBEDTLS_DHM_C)
+ mbedtls_dhm_free( &handshake->dhm_ctx );
+#endif
+#if defined(MBEDTLS_ECDH_C)
+ mbedtls_ecdh_free( &handshake->ecdh_ctx );
+#endif
+#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
+#if defined(MBEDTLS_SSL_CLI_C)
+ mbedtls_free( handshake->ecjpake_cache );
+ handshake->ecjpake_cache = NULL;
+ handshake->ecjpake_cache_len = 0;
+#endif
+#endif
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
+#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
+ /* explicit void pointer cast for buggy MS compiler */
+ mbedtls_free( (void *) handshake->curves );
+#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
+ if( handshake->psk != NULL )
{
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- if( ssl->handshake != NULL &&
- ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
- {
- if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
- return( ret );
- }
+ mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
+ mbedtls_free( handshake->psk );
}
#endif
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/*
- * Check if renegotiation is necessary and/or handshake is
- * in process. If yes, perform/continue, and fall through
- * if an unexpected packet is received while the client
- * is waiting for the ServerHello.
- *
- * (There is no equivalent to the last condition on
- * the server-side as it is not treated as within
- * a handshake while waiting for the ClientHello
- * after a renegotiation request.)
+ * Free only the linked list wrapper, not the keys themselves
+ * since the belong to the SNI callback
*/
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- ret = ssl_check_ctr_renegotiate( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
+ if( handshake->sni_key_cert != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
-#endif
+ mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
- {
- ret = mbedtls_ssl_handshake( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
+ while( cur != NULL )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
+ next = cur->next;
+ mbedtls_free( cur );
+ cur = next;
}
}
+#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
- /* Loop as long as no application data record is available */
- while( ssl->in_offt == NULL )
+#if defined(MBEDTLS_SSL_ECP_RESTARTABLE_ENABLED)
+ mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
+ if( handshake->ecrs_peer_cert != NULL )
{
- /* Start timer if not already running */
- if( ssl->f_get_timer != NULL &&
- ssl->f_get_timer( ssl->p_timer ) == -1 )
- {
- ssl_set_timer( ssl, ssl->conf->read_timeout );
- }
-
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
+ mbedtls_x509_crt_free( handshake->ecrs_peer_cert );
+ mbedtls_free( handshake->ecrs_peer_cert );
+ }
+#endif
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
+#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_free( &handshake->peer_pubkey );
+#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
- if( ssl->in_msglen == 0 &&
- ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- /*
- * OpenSSL sends empty messages to randomize the IV
- */
- if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 )
- {
- if( ret == MBEDTLS_ERR_SSL_CONN_EOF )
- return( 0 );
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ mbedtls_free( handshake->verify_cookie );
+ mbedtls_ssl_flight_free( handshake->flight );
+ mbedtls_ssl_buffering_free( ssl );
+#endif
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
- return( ret );
- }
- }
+#if defined(MBEDTLS_ECDH_C) && \
+ defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_destroy_key( handshake->ecdh_psa_privkey );
+#endif /* MBEDTLS_ECDH_C && MBEDTLS_USE_PSA_CRYPTO */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) );
+ mbedtls_platform_zeroize( handshake,
+ sizeof( mbedtls_ssl_handshake_params ) );
- /*
- * - For client-side, expect SERVER_HELLO_REQUEST.
- * - For server-side, expect CLIENT_HELLO.
- * - Fail (TLS) or silently drop record (DTLS) in other cases.
- */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too big - reallocate. Because of the way Mbed TLS
+ * processes datagrams and the fact that a datagram is allowed to have
+ * several records in it, it is possible that the I/O buffers are not
+ * empty at this stage */
+ handle_buffer_resizing( ssl, 1, mbedtls_ssl_get_input_buflen( ssl ),
+ mbedtls_ssl_get_output_buflen( ssl ) );
+#endif
+}
-#if defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ||
- ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) );
+void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
+{
+ if( session == NULL )
+ return;
- /* With DTLS, drop the packet (probably from last handshake) */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- continue;
- }
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ ssl_clear_peer_cert( session );
#endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
-#endif /* MBEDTLS_SSL_CLI_C */
-
-#if defined(MBEDTLS_SSL_SRV_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) );
- /* With DTLS, drop the packet (probably from last handshake) */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- continue;
- }
+#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
+ mbedtls_free( session->ticket );
#endif
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
-#endif /* MBEDTLS_SSL_SRV_C */
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- /* Determine whether renegotiation attempt should be accepted */
- if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
- ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION &&
- ssl->conf->allow_legacy_renegotiation ==
- MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) )
- {
- /*
- * Accept renegotiation request
- */
+ mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
+}
- /* DTLS clients need to know renego is server-initiated */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
- ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
- {
- ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
- }
-#endif
- ret = ssl_start_renegotiation( ssl );
- if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO &&
- ret != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret );
- return( ret );
- }
- }
- else
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
- {
- /*
- * Refuse renegotiation
- */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
- MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID 0u
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
-#if defined(MBEDTLS_SSL_PROTO_SSL3)
- if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
- {
- /* SSLv3 does not have a "no_renegotiation" warning, so
- we send a fatal alert and abort the connection. */
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_SSL3 */
-#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_2)
- if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 )
- {
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 )
- {
- return( ret );
- }
- }
- else
-#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 ||
- MBEDTLS_SSL_PROTO_TLS1_2 */
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
- return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
- }
- }
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT 0u
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
- /* At this point, we don't know whether the renegotiation has been
- * completed or not. The cases to consider are the following:
- * 1) The renegotiation is complete. In this case, no new record
- * has been read yet.
- * 2) The renegotiation is incomplete because the client received
- * an application data record while awaiting the ServerHello.
- * 3) The renegotiation is incomplete because the client received
- * a non-handshake, non-application data message while awaiting
- * the ServerHello.
- * In each of these case, looping will be the proper action:
- * - For 1), the next iteration will read a new record and check
- * if it's application data.
- * - For 2), the loop condition isn't satisfied as application data
- * is present, hence continue is the same as break
- * - For 3), the loop condition is satisfied and read_record
- * will re-deliver the message that was held back by the client
- * when expecting the ServerHello.
- */
- continue;
- }
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ssl->conf->renego_max_records >= 0 )
- {
- if( ++ssl->renego_records_seen > ssl->conf->renego_max_records )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, "
- "but not honored by client" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
- }
- }
-#endif /* MBEDTLS_SSL_RENEGOTIATION */
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY 0u
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */
- if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) );
- return( MBEDTLS_ERR_SSL_WANT_READ );
- }
+#if defined(MBEDTLS_SSL_ALPN)
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 1u
+#else
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN 0u
+#endif /* MBEDTLS_SSL_ALPN */
- if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) );
- return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
- }
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT 0
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT 1
+#define SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT 2
+#define SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT 3
+
+#define SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG \
+ ( (uint32_t) ( \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_CONNECTION_ID_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_BADMAC_LIMIT_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY << SSL_SERIALIZED_CONTEXT_CONFIG_DTLS_ANTI_REPLAY_BIT ) | \
+ ( SSL_SERIALIZED_CONTEXT_CONFIG_ALPN << SSL_SERIALIZED_CONTEXT_CONFIG_ALPN_BIT ) | \
+ 0u ) )
+
+static unsigned char ssl_serialized_context_header[] = {
+ MBEDTLS_VERSION_MAJOR,
+ MBEDTLS_VERSION_MINOR,
+ MBEDTLS_VERSION_PATCH,
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_SESSION_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_2( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_1( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+ MBEDTLS_BYTE_0( SSL_SERIALIZED_CONTEXT_CONFIG_BITFLAG ),
+};
- ssl->in_offt = ssl->in_msg;
+/*
+ * Serialize a full SSL context
+ *
+ * The format of the serialized data is:
+ * (in the presentation language of TLS, RFC 8446 section 3)
+ *
+ * // header
+ * opaque mbedtls_version[3]; // major, minor, patch
+ * opaque context_format[5]; // version-specific field determining
+ * // the format of the remaining
+ * // serialized data.
+ * Note: When updating the format, remember to keep these
+ * version+format bytes. (We may make their size part of the API.)
+ *
+ * // session sub-structure
+ * opaque session<1..2^32-1>; // see mbedtls_ssl_session_save()
+ * // transform sub-structure
+ * uint8 random[64]; // ServerHello.random+ClientHello.random
+ * uint8 in_cid<0..2^8-1> // Connection ID: expected incoming value
+ * uint8 out_cid<0..2^8-1> // Connection ID: outgoing value to use
+ * // fields from ssl_context
+ * uint32 badmac_seen; // DTLS: number of records with failing MAC
+ * uint64 in_window_top; // DTLS: last validated record seq_num
+ * uint64 in_window; // DTLS: bitmask for replay protection
+ * uint8 disable_datagram_packing; // DTLS: only one record per datagram
+ * uint64 cur_out_ctr; // Record layer: outgoing sequence number
+ * uint16 mtu; // DTLS: path mtu (max outgoing fragment size)
+ * uint8 alpn_chosen<0..2^8-1> // ALPN: negotiated application protocol
+ *
+ * Note that many fields of the ssl_context or sub-structures are not
+ * serialized, as they fall in one of the following categories:
+ *
+ * 1. forced value (eg in_left must be 0)
+ * 2. pointer to dynamically-allocated memory (eg session, transform)
+ * 3. value can be re-derived from other data (eg session keys from MS)
+ * 4. value was temporary (eg content of input buffer)
+ * 5. value will be provided by the user again (eg I/O callbacks and context)
+ */
+int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
+ unsigned char *buf,
+ size_t buf_len,
+ size_t *olen )
+{
+ unsigned char *p = buf;
+ size_t used = 0;
+ size_t session_len;
+ int ret = 0;
- /* We're going to return something now, cancel timer,
- * except if handshake (renegotiation) is in progress */
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
- ssl_set_timer( ssl, 0 );
+ /*
+ * Enforce usage restrictions, see "return BAD_INPUT_DATA" in
+ * this function's documentation.
+ *
+ * These are due to assumptions/limitations in the implementation. Some of
+ * them are likely to stay (no handshake in progress) some might go away
+ * (only DTLS) but are currently used to simplify the implementation.
+ */
+ /* The initial handshake must be over */
+ if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Initial handshake isn't over" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->handshake != NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Handshake isn't completed" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Double-check that sub-structures are indeed ready */
+ if( ssl->transform == NULL || ssl->session == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Serialised structures aren't ready" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* There must be no pending incoming or outgoing data */
+ if( mbedtls_ssl_check_pending( ssl ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "There is pending incoming data" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->out_left != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "There is pending outgoing data" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Protocol must be DLTS, not TLS */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only DTLS is supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Version must be 1.2 */
+ if( ssl->major_ver != MBEDTLS_SSL_MAJOR_VERSION_3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only version 1.2 supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only version 1.2 supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* We must be using an AEAD ciphersuite */
+ if( mbedtls_ssl_transform_uses_aead( ssl->transform ) != 1 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Only AEAD ciphersuites supported" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /* Renegotiation must not be enabled */
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ if( ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Renegotiation must not be enabled" ) );
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+#endif
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- /* If we requested renego but received AppData, resend HelloRequest.
- * Do it now, after setting in_offt, to avoid taking this branch
- * again if ssl_write_hello_request() returns WANT_WRITE */
-#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
- {
- if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret );
- return( ret );
- }
- }
-#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ /*
+ * Version and format identifier
+ */
+ used += sizeof( ssl_serialized_context_header );
+
+ if( used <= buf_len )
+ {
+ memcpy( p, ssl_serialized_context_header,
+ sizeof( ssl_serialized_context_header ) );
+ p += sizeof( ssl_serialized_context_header );
}
- n = ( len < ssl->in_msglen )
- ? len : ssl->in_msglen;
+ /*
+ * Session (length + data)
+ */
+ ret = ssl_session_save( ssl->session, 1, NULL, 0, &session_len );
+ if( ret != MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL )
+ return( ret );
+
+ used += 4 + session_len;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT32_BE( session_len, p, 0 );
+ p += 4;
- memcpy( buf, ssl->in_offt, n );
- ssl->in_msglen -= n;
+ ret = ssl_session_save( ssl->session, 1,
+ p, session_len, &session_len );
+ if( ret != 0 )
+ return( ret );
- /* Zeroising the plaintext buffer to erase unused application data
- from the memory. */
- mbedtls_platform_zeroize( ssl->in_offt, n );
+ p += session_len;
+ }
- if( ssl->in_msglen == 0 )
+ /*
+ * Transform
+ */
+ used += sizeof( ssl->transform->randbytes );
+ if( used <= buf_len )
{
- /* all bytes consumed */
- ssl->in_offt = NULL;
- ssl->keep_current_message = 0;
+ memcpy( p, ssl->transform->randbytes,
+ sizeof( ssl->transform->randbytes ) );
+ p += sizeof( ssl->transform->randbytes );
}
- else
+
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ used += 2 + ssl->transform->in_cid_len + ssl->transform->out_cid_len;
+ if( used <= buf_len )
{
- /* more data available */
- ssl->in_offt += n;
+ *p++ = ssl->transform->in_cid_len;
+ memcpy( p, ssl->transform->in_cid, ssl->transform->in_cid_len );
+ p += ssl->transform->in_cid_len;
+
+ *p++ = ssl->transform->out_cid_len;
+ memcpy( p, ssl->transform->out_cid, ssl->transform->out_cid_len );
+ p += ssl->transform->out_cid_len;
}
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) );
+ /*
+ * Saved fields from top-level ssl_context structure
+ */
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ used += 4;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT32_BE( ssl->badmac_seen, p, 0 );
+ p += 4;
+ }
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
- return( (int) n );
-}
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ used += 16;
+ if( used <= buf_len )
+ {
+ MBEDTLS_PUT_UINT64_BE( ssl->in_window_top, p, 0 );
+ p += 8;
-/*
- * Send application data to be encrypted by the SSL layer, taking care of max
- * fragment length and buffer size.
- *
- * According to RFC 5246 Section 6.2.1:
- *
- * Zero-length fragments of Application data MAY be sent as they are
- * potentially useful as a traffic analysis countermeasure.
- *
- * Therefore, it is possible that the input message length is 0 and the
- * corresponding return code is 0 on success.
- */
-static int ssl_write_real( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
-{
- int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
- const size_t max_len = (size_t) ret;
+ MBEDTLS_PUT_UINT64_BE( ssl->in_window, p, 0 );
+ p += 8;
+ }
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- if( ret < 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ used += 1;
+ if( used <= buf_len )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_get_max_out_record_payload", ret );
- return( ret );
+ *p++ = ssl->disable_datagram_packing;
}
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
- if( len > max_len )
+ used += 8;
+ if( used <= buf_len )
{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
- "maximum fragment length: %d > %d",
- len, max_len ) );
- return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- }
- else
-#endif
- len = max_len;
+ memcpy( p, ssl->cur_out_ctr, 8 );
+ p += 8;
}
- if( ssl->out_left != 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ used += 2;
+ if( used <= buf_len )
{
- /*
- * The user has previously tried to send the data and
- * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially
- * written. In this case, we expect the high-level write function
- * (e.g. mbedtls_ssl_write()) to be called with the same parameters
- */
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret );
- return( ret );
- }
+ MBEDTLS_PUT_UINT16_BE( ssl->mtu, p, 0 );
+ p += 2;
}
- else
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_ALPN)
{
- /*
- * The user is trying to send a message the first time, so we need to
- * copy the data into the internal buffers and setup the data structure
- * to keep track of partial writes
- */
- ssl->out_msglen = len;
- ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA;
- memcpy( ssl->out_msg, buf, len );
+ const uint8_t alpn_len = ssl->alpn_chosen
+ ? (uint8_t) strlen( ssl->alpn_chosen )
+ : 0;
- if( ( ret = mbedtls_ssl_write_record( ssl, SSL_FORCE_FLUSH ) ) != 0 )
+ used += 1 + alpn_len;
+ if( used <= buf_len )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
- return( ret );
+ *p++ = alpn_len;
+
+ if( ssl->alpn_chosen != NULL )
+ {
+ memcpy( p, ssl->alpn_chosen, alpn_len );
+ p += alpn_len;
+ }
}
}
+#endif /* MBEDTLS_SSL_ALPN */
+
+ /*
+ * Done
+ */
+ *olen = used;
- return( (int) len );
+ if( used > buf_len )
+ return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
+
+ MBEDTLS_SSL_DEBUG_BUF( 4, "saved context", buf, used );
+
+ return( mbedtls_ssl_session_reset_int( ssl, 0 ) );
}
/*
- * Write application data, doing 1/n-1 splitting if necessary.
- *
- * With non-blocking I/O, ssl_write_real() may return WANT_WRITE,
- * then the caller will call us again with the same arguments, so
- * remember whether we already did the split or not.
+ * Helper to get TLS 1.2 PRF from ciphersuite
+ * (Duplicates bits of logic from ssl_set_handshake_prfs().)
*/
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
-static int ssl_write_split( mbedtls_ssl_context *ssl,
- const unsigned char *buf, size_t len )
+typedef int (*tls_prf_fn)( const unsigned char *secret, size_t slen,
+ const char *label,
+ const unsigned char *random, size_t rlen,
+ unsigned char *dstbuf, size_t dlen );
+static tls_prf_fn ssl_tls12prf_from_cs( int ciphersuite_id )
{
- int ret;
-
- if( ssl->conf->cbc_record_splitting ==
- MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ||
- len <= 1 ||
- ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 ||
- mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
- != MBEDTLS_MODE_CBC )
- {
- return( ssl_write_real( ssl, buf, len ) );
- }
-
- if( ssl->split_done == 0 )
- {
- if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 1;
- }
-
- if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 )
- return( ret );
- ssl->split_done = 0;
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
+ const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
+ mbedtls_ssl_ciphersuite_from_id( ciphersuite_id );
- return( ret + 1 );
+ if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
+ return( tls_prf_sha384 );
+#else
+ (void) ciphersuite_id;
+#endif
+ return( tls_prf_sha256 );
}
-#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
/*
- * Write application data (public-facing wrapper)
+ * Deserialize context, see mbedtls_ssl_context_save() for format.
+ *
+ * This internal version is wrapped by a public function that cleans up in
+ * case of error.
*/
-int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
+static int ssl_context_load( mbedtls_ssl_context *ssl,
+ const unsigned char *buf,
+ size_t len )
{
- int ret;
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) );
+ const unsigned char *p = buf;
+ const unsigned char * const end = buf + len;
+ size_t session_len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
- if( ssl == NULL || ssl->conf == NULL )
+ /*
+ * The context should have been freshly setup or reset.
+ * Give the user an error in case of obvious misuse.
+ * (Checking session is useful because it won't be NULL if we're
+ * renegotiating, or if the user mistakenly loaded a session first.)
+ */
+ if( ssl->state != MBEDTLS_SSL_HELLO_REQUEST ||
+ ssl->session != NULL )
+ {
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ }
+ /*
+ * We can't check that the config matches the initial one, but we can at
+ * least check it matches the requirements for serializing.
+ */
+ if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ ssl->conf->max_major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 ||
+ ssl->conf->min_major_ver > MBEDTLS_SSL_MAJOR_VERSION_3 ||
+ ssl->conf->max_minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ||
+ ssl->conf->min_minor_ver > MBEDTLS_SSL_MINOR_VERSION_3 ||
#if defined(MBEDTLS_SSL_RENEGOTIATION)
- if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret );
- return( ret );
- }
+ ssl->conf->disable_renegotiation != MBEDTLS_SSL_RENEGOTIATION_DISABLED ||
#endif
-
- if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
+ 0 )
{
- if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret );
- return( ret );
- }
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- ret = ssl_write_split( ssl, buf, len );
-#else
- ret = ssl_write_real( ssl, buf, len );
-#endif
-
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "context to load", buf, len );
- return( ret );
-}
+ /*
+ * Check version identifier
+ */
+ if( (size_t)( end - p ) < sizeof( ssl_serialized_context_header ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-/*
- * Notify the peer that the connection is being closed
- */
-int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl )
-{
- int ret;
+ if( memcmp( p, ssl_serialized_context_header,
+ sizeof( ssl_serialized_context_header ) ) != 0 )
+ {
+ return( MBEDTLS_ERR_SSL_VERSION_MISMATCH );
+ }
+ p += sizeof( ssl_serialized_context_header );
- if( ssl == NULL || ssl->conf == NULL )
+ /*
+ * Session
+ */
+ if( (size_t)( end - p ) < 4 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) );
+ session_len = ( (size_t) p[0] << 24 ) |
+ ( (size_t) p[1] << 16 ) |
+ ( (size_t) p[2] << 8 ) |
+ ( (size_t) p[3] );
+ p += 4;
- if( ssl->out_left != 0 )
- return( mbedtls_ssl_flush_output( ssl ) );
+ /* This has been allocated by ssl_handshake_init(), called by
+ * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
+ ssl->session = ssl->session_negotiate;
+ ssl->session_in = ssl->session;
+ ssl->session_out = ssl->session;
+ ssl->session_negotiate = NULL;
- if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ if( (size_t)( end - p ) < session_len )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ret = ssl_session_load( ssl->session, 1, p, session_len );
+ if( ret != 0 )
{
- if( ( ret = mbedtls_ssl_send_alert_message( ssl,
- MBEDTLS_SSL_ALERT_LEVEL_WARNING,
- MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret );
- return( ret );
- }
+ mbedtls_ssl_session_free( ssl->session );
+ return( ret );
}
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) );
+ p += session_len;
- return( 0 );
-}
+ /*
+ * Transform
+ */
-void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
-{
- if( transform == NULL )
- return;
+ /* This has been allocated by ssl_handshake_init(), called by
+ * by either mbedtls_ssl_session_reset_int() or mbedtls_ssl_setup(). */
+ ssl->transform = ssl->transform_negotiate;
+ ssl->transform_in = ssl->transform;
+ ssl->transform_out = ssl->transform;
+ ssl->transform_negotiate = NULL;
+
+ /* Read random bytes and populate structure */
+ if( (size_t)( end - p ) < sizeof( ssl->transform->randbytes ) )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ ret = ssl_populate_transform( ssl->transform,
+ ssl->session->ciphersuite,
+ ssl->session->master,
+#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ ssl->session->encrypt_then_mac,
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ ssl->session->trunc_hmac,
+#endif
+#endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
#if defined(MBEDTLS_ZLIB_SUPPORT)
- deflateEnd( &transform->ctx_deflate );
- inflateEnd( &transform->ctx_inflate );
+ ssl->session->compression,
#endif
+ ssl_tls12prf_from_cs( ssl->session->ciphersuite ),
+ p, /* currently pointing to randbytes */
+ MBEDTLS_SSL_MINOR_VERSION_3, /* (D)TLS 1.2 is forced */
+ ssl->conf->endpoint,
+ ssl );
+ if( ret != 0 )
+ return( ret );
- mbedtls_cipher_free( &transform->cipher_ctx_enc );
- mbedtls_cipher_free( &transform->cipher_ctx_dec );
+ p += sizeof( ssl->transform->randbytes );
- mbedtls_md_free( &transform->md_ctx_enc );
- mbedtls_md_free( &transform->md_ctx_dec );
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ /* Read connection IDs and store them */
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- mbedtls_platform_zeroize( transform, sizeof( mbedtls_ssl_transform ) );
-}
+ ssl->transform->in_cid_len = *p++;
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
-static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
-{
- mbedtls_ssl_key_cert *cur = key_cert, *next;
+ if( (size_t)( end - p ) < ssl->transform->in_cid_len + 1u )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
-}
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
+ memcpy( ssl->transform->in_cid, p, ssl->transform->in_cid_len );
+ p += ssl->transform->in_cid_len;
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ ssl->transform->out_cid_len = *p++;
-static void ssl_buffering_free( mbedtls_ssl_context *ssl )
-{
- unsigned offset;
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
+ if( (size_t)( end - p ) < ssl->transform->out_cid_len )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( hs == NULL )
- return;
+ memcpy( ssl->transform->out_cid, p, ssl->transform->out_cid_len );
+ p += ssl->transform->out_cid_len;
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
- ssl_free_buffered_record( ssl );
+ /*
+ * Saved fields from top-level ssl_context structure
+ */
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+ if( (size_t)( end - p ) < 4 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- for( offset = 0; offset < MBEDTLS_SSL_MAX_BUFFERED_HS; offset++ )
- ssl_buffering_free_slot( ssl, offset );
-}
+ ssl->badmac_seen = ( (uint32_t) p[0] << 24 ) |
+ ( (uint32_t) p[1] << 16 ) |
+ ( (uint32_t) p[2] << 8 ) |
+ ( (uint32_t) p[3] );
+ p += 4;
+#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
-static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl,
- uint8_t slot )
-{
- mbedtls_ssl_handshake_params * const hs = ssl->handshake;
- mbedtls_ssl_hs_buffer * const hs_buf = &hs->buffering.hs[slot];
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+ if( (size_t)( end - p ) < 16 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( slot >= MBEDTLS_SSL_MAX_BUFFERED_HS )
- return;
+ ssl->in_window_top = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+
+ ssl->in_window = ( (uint64_t) p[0] << 56 ) |
+ ( (uint64_t) p[1] << 48 ) |
+ ( (uint64_t) p[2] << 40 ) |
+ ( (uint64_t) p[3] << 32 ) |
+ ( (uint64_t) p[4] << 24 ) |
+ ( (uint64_t) p[5] << 16 ) |
+ ( (uint64_t) p[6] << 8 ) |
+ ( (uint64_t) p[7] );
+ p += 8;
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
- if( hs_buf->is_valid == 1 )
- {
- hs->buffering.total_bytes_buffered -= hs_buf->data_len;
- mbedtls_platform_zeroize( hs_buf->data, hs_buf->data_len );
- mbedtls_free( hs_buf->data );
- memset( hs_buf, 0, sizeof( mbedtls_ssl_hs_buffer ) );
- }
-}
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+ ssl->disable_datagram_packing = *p++;
#endif /* MBEDTLS_SSL_PROTO_DTLS */
-void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
-{
- mbedtls_ssl_handshake_params *handshake = ssl->handshake;
+ if( (size_t)( end - p ) < 8 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
- if( handshake == NULL )
- return;
+ memcpy( ssl->cur_out_ctr, p, 8 );
+ p += 8;
-#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
- if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( (size_t)( end - p ) < 2 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl->mtu = ( p[0] << 8 ) | p[1];
+ p += 2;
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_ALPN)
{
- ssl->conf->f_async_cancel( ssl );
- handshake->async_in_progress = 0;
- }
-#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+ uint8_t alpn_len;
+ const char **cur;
-#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
- defined(MBEDTLS_SSL_PROTO_TLS1_1)
- mbedtls_md5_free( &handshake->fin_md5 );
- mbedtls_sha1_free( &handshake->fin_sha1 );
-#endif
-#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
-#if defined(MBEDTLS_SHA256_C)
- mbedtls_sha256_free( &handshake->fin_sha256 );
-#endif
-#if defined(MBEDTLS_SHA512_C)
- mbedtls_sha512_free( &handshake->fin_sha512 );
-#endif
-#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+ if( (size_t)( end - p ) < 1 )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
-#if defined(MBEDTLS_DHM_C)
- mbedtls_dhm_free( &handshake->dhm_ctx );
-#endif
-#if defined(MBEDTLS_ECDH_C)
- mbedtls_ecdh_free( &handshake->ecdh_ctx );
-#endif
-#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
-#if defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( handshake->ecjpake_cache );
- handshake->ecjpake_cache = NULL;
- handshake->ecjpake_cache_len = 0;
-#endif
-#endif
+ alpn_len = *p++;
-#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
- defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
- /* explicit void pointer cast for buggy MS compiler */
- mbedtls_free( (void *) handshake->curves );
-#endif
+ if( alpn_len != 0 && ssl->conf->alpn_list != NULL )
+ {
+ /* alpn_chosen should point to an item in the configured list */
+ for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
+ {
+ if( strlen( *cur ) == alpn_len &&
+ memcmp( p, cur, alpn_len ) == 0 )
+ {
+ ssl->alpn_chosen = *cur;
+ break;
+ }
+ }
+ }
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
- if( handshake->psk != NULL )
- {
- mbedtls_platform_zeroize( handshake->psk, handshake->psk_len );
- mbedtls_free( handshake->psk );
+ /* can only happen on conf mismatch */
+ if( alpn_len != 0 && ssl->alpn_chosen == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ p += alpn_len;
}
-#endif
+#endif /* MBEDTLS_SSL_ALPN */
-#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
- defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
/*
- * Free only the linked list wrapper, not the keys themselves
- * since the belong to the SNI callback
+ * Forced fields from top-level ssl_context structure
+ *
+ * Most of them already set to the correct value by mbedtls_ssl_init() and
+ * mbedtls_ssl_reset(), so we only need to set the remaining ones.
*/
- if( handshake->sni_key_cert != NULL )
- {
- mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next;
+ ssl->state = MBEDTLS_SSL_HANDSHAKE_OVER;
- while( cur != NULL )
- {
- next = cur->next;
- mbedtls_free( cur );
- cur = next;
- }
- }
-#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */
+ ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
+ ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
-#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
- mbedtls_x509_crt_restart_free( &handshake->ecrs_ctx );
-#endif
+ /* Adjust pointers for header fields of outgoing records to
+ * the given transform, accounting for explicit IV and CID. */
+ mbedtls_ssl_update_out_pointers( ssl, ssl->transform );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- mbedtls_free( handshake->verify_cookie );
- ssl_flight_free( handshake->flight );
- ssl_buffering_free( ssl );
+ ssl->in_epoch = 1;
#endif
- mbedtls_platform_zeroize( handshake,
- sizeof( mbedtls_ssl_handshake_params ) );
+ /* mbedtls_ssl_reset() leaves the handshake sub-structure allocated,
+ * which we don't want - otherwise we'd end up freeing the wrong transform
+ * by calling mbedtls_ssl_handshake_wrapup_free_hs_transform()
+ * inappropriately. */
+ if( ssl->handshake != NULL )
+ {
+ mbedtls_ssl_handshake_free( ssl );
+ mbedtls_free( ssl->handshake );
+ ssl->handshake = NULL;
+ }
+
+ /*
+ * Done - should have consumed entire buffer
+ */
+ if( p != end )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ return( 0 );
}
-void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
+/*
+ * Deserialize context: public wrapper for error cleaning
+ */
+int mbedtls_ssl_context_load( mbedtls_ssl_context *context,
+ const unsigned char *buf,
+ size_t len )
{
- if( session == NULL )
- return;
-
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- if( session->peer_cert != NULL )
- {
- mbedtls_x509_crt_free( session->peer_cert );
- mbedtls_free( session->peer_cert );
- }
-#endif
+ int ret = ssl_context_load( context, buf, len );
-#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
- mbedtls_free( session->ticket );
-#endif
+ if( ret != 0 )
+ mbedtls_ssl_free( context );
- mbedtls_platform_zeroize( session, sizeof( mbedtls_ssl_session ) );
+ return( ret );
}
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
/*
* Free an SSL context
@@ -9238,14 +6801,28 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
if( ssl->out_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+
+ mbedtls_platform_zeroize( ssl->out_buf, out_buf_len );
mbedtls_free( ssl->out_buf );
+ ssl->out_buf = NULL;
}
if( ssl->in_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+
+ mbedtls_platform_zeroize( ssl->in_buf, in_buf_len );
mbedtls_free( ssl->in_buf );
+ ssl->in_buf = NULL;
}
#if defined(MBEDTLS_ZLIB_SUPPORT)
@@ -9313,10 +6890,12 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
memset( conf, 0, sizeof( mbedtls_ssl_config ) );
}
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_preset_default_hashes[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
+#endif
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
MBEDTLS_MD_SHA384,
#endif
#if defined(MBEDTLS_SHA256_C)
@@ -9336,7 +6915,7 @@ static int ssl_preset_suiteb_ciphersuites[] = {
0
};
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
static int ssl_preset_suiteb_hashes[] = {
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA384,
@@ -9363,7 +6942,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
int endpoint, int transport, int preset )
{
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#endif
/* Use the functions here so that they are covered in tests,
@@ -9465,7 +7044,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
conf->sig_hashes = ssl_preset_suiteb_hashes;
#endif
@@ -9504,7 +7083,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_default;
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
conf->sig_hashes = ssl_preset_default_hashes;
#endif
@@ -9530,7 +7109,7 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
mbedtls_mpi_free( &conf->dhm_G );
#endif
-#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED)
if( conf->psk != NULL )
{
mbedtls_platform_zeroize( conf->psk, conf->psk_len );
@@ -9605,7 +7184,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
- defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+ defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/* Find an entry in a signature-hash set matching a given hash algorithm. */
mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set,
@@ -9653,7 +7232,7 @@ void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set,
}
#endif /* MBEDTLS_SSL_PROTO_TLS1_2) &&
- MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+ MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
/*
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
@@ -9676,9 +7255,11 @@ mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash )
case MBEDTLS_SSL_HASH_SHA256:
return( MBEDTLS_MD_SHA256 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_SSL_HASH_SHA384:
return( MBEDTLS_MD_SHA384 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_SSL_HASH_SHA512:
return( MBEDTLS_MD_SHA512 );
#endif
@@ -9708,9 +7289,11 @@ unsigned char mbedtls_ssl_hash_from_md_alg( int md )
case MBEDTLS_MD_SHA256:
return( MBEDTLS_SSL_HASH_SHA256 );
#endif
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_MD_SHA384:
return( MBEDTLS_SSL_HASH_SHA384 );
+#endif
+#if defined(MBEDTLS_SHA512_C)
case MBEDTLS_MD_SHA512:
return( MBEDTLS_SSL_HASH_SHA512 );
#endif
@@ -9739,7 +7322,7 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i
}
#endif /* MBEDTLS_ECP_C */
-#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
+#if defined(MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED)
/*
* Check if a hash proposed by the peer is in our list.
* Return 0 if we're willing to use it, -1 otherwise.
@@ -9758,7 +7341,7 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
return( -1 );
}
-#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
+#endif /* MBEDTLS_KEY_EXCHANGE_WITH_CERT_ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
@@ -9851,59 +7434,6 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
-/*
- * Convert version numbers to/from wire format
- * and, for DTLS, to/from TLS equivalent.
- *
- * For TLS this is the identity.
- * For DTLS, use 1's complement (v -> 255 - v, and then map as follows:
- * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1)
- * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2)
- */
-void mbedtls_ssl_write_version( int major, int minor, int transport,
- unsigned char ver[2] )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
- --minor; /* DTLS 1.0 stored as TLS 1.1 internally */
-
- ver[0] = (unsigned char)( 255 - ( major - 2 ) );
- ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
- }
- else
-#else
- ((void) transport);
-#endif
- {
- ver[0] = (unsigned char) major;
- ver[1] = (unsigned char) minor;
- }
-}
-
-void mbedtls_ssl_read_version( int *major, int *minor, int transport,
- const unsigned char ver[2] )
-{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- *major = 255 - ver[0] + 2;
- *minor = 255 - ver[1] + 1;
-
- if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
- ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
- }
- else
-#else
- ((void) transport);
-#endif
- {
- *major = ver[0];
- *minor = ver[1];
- }
-}
-
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
{
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -9923,7 +7453,7 @@ int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
break;
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */
-#if defined(MBEDTLS_SHA512_C)
+#if defined(MBEDTLS_SHA512_C) && !defined(MBEDTLS_SHA512_NO_SHA384)
case MBEDTLS_SSL_HASH_SHA384:
ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384;
break;
@@ -10034,6 +7564,70 @@ exit:
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
defined(MBEDTLS_SSL_PROTO_TLS1_2)
+
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
+ unsigned char *hash, size_t *hashlen,
+ unsigned char *data, size_t data_len,
+ mbedtls_md_type_t md_alg )
+{
+ psa_status_t status;
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( md_alg );
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform PSA-based computation of digest of ServerKeyExchange" ) );
+
+ if( ( status = psa_hash_setup( &hash_operation,
+ hash_alg ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_setup", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation, ssl->handshake->randbytes,
+ 64 ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_update( &hash_operation,
+ data, data_len ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_update", status );
+ goto exit;
+ }
+
+ if( ( status = psa_hash_finish( &hash_operation, hash, PSA_HASH_MAX_SIZE,
+ hashlen ) ) != PSA_SUCCESS )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "psa_hash_finish", status );
+ goto exit;
+ }
+
+exit:
+ if( status != PSA_SUCCESS )
+ {
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ switch( status )
+ {
+ case PSA_ERROR_NOT_SUPPORTED:
+ return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE );
+ case PSA_ERROR_BAD_STATE: /* Intentional fallthrough */
+ case PSA_ERROR_BUFFER_TOO_SMALL:
+ return( MBEDTLS_ERR_MD_BAD_INPUT_DATA );
+ case PSA_ERROR_INSUFFICIENT_MEMORY:
+ return( MBEDTLS_ERR_MD_ALLOC_FAILED );
+ default:
+ return( MBEDTLS_ERR_MD_HW_ACCEL_FAILED );
+ }
+ }
+ return( 0 );
+}
+
+#else
+
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
unsigned char *hash, size_t *hashlen,
unsigned char *data, size_t data_len,
@@ -10044,6 +7638,8 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
*hashlen = mbedtls_md_get_size( md_info );
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Perform mbedtls-based computation of digest of ServerKeyExchange" ) );
+
mbedtls_md_init( &ctx );
/*
@@ -10088,6 +7684,8 @@ exit:
return( ret );
}
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
MBEDTLS_SSL_PROTO_TLS1_2 */
diff --git a/thirdparty/mbedtls/library/ssl_tls13_keys.c b/thirdparty/mbedtls/library/ssl_tls13_keys.c
new file mode 100644
index 0000000000..3de6f03fb8
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_tls13_keys.c
@@ -0,0 +1,349 @@
+/*
+ * TLS 1.3 key schedule
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" ); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common.h"
+
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+
+#include "mbedtls/hkdf.h"
+#include "mbedtls/ssl_internal.h"
+#include "ssl_tls13_keys.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
+ .name = string,
+
+struct mbedtls_ssl_tls1_3_labels_struct const mbedtls_ssl_tls1_3_labels =
+{
+ /* This seems to work in C, despite the string literal being one
+ * character too long due to the 0-termination. */
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+
+#undef MBEDTLS_SSL_TLS1_3_LABEL
+
+/*
+ * This function creates a HkdfLabel structure used in the TLS 1.3 key schedule.
+ *
+ * The HkdfLabel is specified in RFC 8446 as follows:
+ *
+ * struct HkdfLabel {
+ * uint16 length; // Length of expanded key material
+ * opaque label<7..255>; // Always prefixed by "tls13 "
+ * opaque context<0..255>; // Usually a communication transcript hash
+ * };
+ *
+ * Parameters:
+ * - desired_length: Length of expanded key material
+ * Even though the standard allows expansion to up to
+ * 2**16 Bytes, TLS 1.3 never uses expansion to more than
+ * 255 Bytes, so we require `desired_length` to be at most
+ * 255. This allows us to save a few Bytes of code by
+ * hardcoding the writing of the high bytes.
+ * - (label, llen): label + label length, without "tls13 " prefix
+ * The label length MUST be less than or equal to
+ * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN
+ * It is the caller's responsibility to ensure this.
+ * All (label, label length) pairs used in TLS 1.3
+ * can be obtained via MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN().
+ * - (ctx, clen): context + context length
+ * The context length MUST be less than or equal to
+ * MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN
+ * It is the caller's responsibility to ensure this.
+ * - dst: Target buffer for HkdfLabel structure,
+ * This MUST be a writable buffer of size
+ * at least SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN Bytes.
+ * - dlen: Pointer at which to store the actual length of
+ * the HkdfLabel structure on success.
+ */
+
+static const char tls1_3_label_prefix[6] = "tls13 ";
+
+#define SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( label_len, context_len ) \
+ ( 2 /* expansion length */ \
+ + 1 /* label length */ \
+ + label_len \
+ + 1 /* context length */ \
+ + context_len )
+
+#define SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN \
+ SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( \
+ sizeof(tls1_3_label_prefix) + \
+ MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN, \
+ MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
+
+static void ssl_tls1_3_hkdf_encode_label(
+ size_t desired_length,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *dst, size_t *dlen )
+{
+ size_t total_label_len =
+ sizeof(tls1_3_label_prefix) + llen;
+ size_t total_hkdf_lbl_len =
+ SSL_TLS1_3_KEY_SCHEDULE_HKDF_LABEL_LEN( total_label_len, clen );
+
+ unsigned char *p = dst;
+
+ /* Add the size of the expanded key material.
+ * We're hardcoding the high byte to 0 here assuming that we never use
+ * TLS 1.3 HKDF key expansion to more than 255 Bytes. */
+#if MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN > 255
+#error "The implementation of ssl_tls1_3_hkdf_encode_label() is not fit for the \
+ value of MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN"
+#endif
+
+ *p++ = 0;
+ *p++ = MBEDTLS_BYTE_0( desired_length );
+
+ /* Add label incl. prefix */
+ *p++ = MBEDTLS_BYTE_0( total_label_len );
+ memcpy( p, tls1_3_label_prefix, sizeof(tls1_3_label_prefix) );
+ p += sizeof(tls1_3_label_prefix);
+ memcpy( p, label, llen );
+ p += llen;
+
+ /* Add context value */
+ *p++ = MBEDTLS_BYTE_0( clen );
+ if( clen != 0 )
+ memcpy( p, ctx, clen );
+
+ /* Return total length to the caller. */
+ *dlen = total_hkdf_lbl_len;
+}
+
+int mbedtls_ssl_tls1_3_hkdf_expand_label(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *buf, size_t blen )
+{
+ const mbedtls_md_info_t *md;
+ unsigned char hkdf_label[ SSL_TLS1_3_KEY_SCHEDULE_MAX_HKDF_LABEL_LEN ];
+ size_t hkdf_label_len;
+
+ if( llen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN )
+ {
+ /* Should never happen since this is an internal
+ * function, and we know statically which labels
+ * are allowed. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( clen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN )
+ {
+ /* Should not happen, as above. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ if( blen > MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN )
+ {
+ /* Should not happen, as above. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ ssl_tls1_3_hkdf_encode_label( blen,
+ label, llen,
+ ctx, clen,
+ hkdf_label,
+ &hkdf_label_len );
+
+ return( mbedtls_hkdf_expand( md,
+ secret, slen,
+ hkdf_label, hkdf_label_len,
+ buf, blen ) );
+}
+
+/*
+ * The traffic keying material is generated from the following inputs:
+ *
+ * - One secret value per sender.
+ * - A purpose value indicating the specific value being generated
+ * - The desired lengths of key and IV.
+ *
+ * The expansion itself is based on HKDF:
+ *
+ * [sender]_write_key = HKDF-Expand-Label( Secret, "key", "", key_length )
+ * [sender]_write_iv = HKDF-Expand-Label( Secret, "iv" , "", iv_length )
+ *
+ * [sender] denotes the sending side and the Secret value is provided
+ * by the function caller. Note that we generate server and client side
+ * keys in a single function call.
+ */
+int mbedtls_ssl_tls1_3_make_traffic_keys(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *client_secret,
+ const unsigned char *server_secret,
+ size_t slen, size_t key_len, size_t iv_len,
+ mbedtls_ssl_key_set *keys )
+{
+ int ret = 0;
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ client_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
+ NULL, 0,
+ keys->client_write_key, key_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ server_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( key ),
+ NULL, 0,
+ keys->server_write_key, key_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ client_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
+ NULL, 0,
+ keys->client_write_iv, iv_len );
+ if( ret != 0 )
+ return( ret );
+
+ ret = mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ server_secret, slen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( iv ),
+ NULL, 0,
+ keys->server_write_iv, iv_len );
+ if( ret != 0 )
+ return( ret );
+
+ keys->key_len = key_len;
+ keys->iv_len = iv_len;
+
+ return( 0 );
+}
+
+int mbedtls_ssl_tls1_3_derive_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ int ctx_hashed,
+ unsigned char *dstbuf, size_t buflen )
+{
+ int ret;
+ unsigned char hashed_context[ MBEDTLS_MD_MAX_SIZE ];
+
+ const mbedtls_md_info_t *md;
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ if( ctx_hashed == MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED )
+ {
+ ret = mbedtls_md( md, ctx, clen, hashed_context );
+ if( ret != 0 )
+ return( ret );
+ clen = mbedtls_md_get_size( md );
+ }
+ else
+ {
+ if( clen > sizeof(hashed_context) )
+ {
+ /* This should never happen since this function is internal
+ * and the code sets `ctx_hashed` correctly.
+ * Let's double-check nonetheless to not run at the risk
+ * of getting a stack overflow. */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ memcpy( hashed_context, ctx, clen );
+ }
+
+ return( mbedtls_ssl_tls1_3_hkdf_expand_label( hash_alg,
+ secret, slen,
+ label, llen,
+ hashed_context, clen,
+ dstbuf, buflen ) );
+}
+
+int mbedtls_ssl_tls1_3_evolve_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret_old,
+ const unsigned char *input, size_t input_len,
+ unsigned char *secret_new )
+{
+ int ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
+ size_t hlen, ilen;
+ unsigned char tmp_secret[ MBEDTLS_MD_MAX_SIZE ] = { 0 };
+ unsigned char tmp_input [ MBEDTLS_MD_MAX_SIZE ] = { 0 };
+
+ const mbedtls_md_info_t *md;
+ md = mbedtls_md_info_from_type( hash_alg );
+ if( md == NULL )
+ return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
+
+ hlen = mbedtls_md_get_size( md );
+
+ /* For non-initial runs, call Derive-Secret( ., "derived", "")
+ * on the old secret. */
+ if( secret_old != NULL )
+ {
+ ret = mbedtls_ssl_tls1_3_derive_secret(
+ hash_alg,
+ secret_old, hlen,
+ MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( derived ),
+ NULL, 0, /* context */
+ MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED,
+ tmp_secret, hlen );
+ if( ret != 0 )
+ goto cleanup;
+ }
+
+ if( input != NULL )
+ {
+ memcpy( tmp_input, input, input_len );
+ ilen = input_len;
+ }
+ else
+ {
+ ilen = hlen;
+ }
+
+ /* HKDF-Extract takes a salt and input key material.
+ * The salt is the old secret, and the input key material
+ * is the input secret (PSK / ECDHE). */
+ ret = mbedtls_hkdf_extract( md,
+ tmp_secret, hlen,
+ tmp_input, ilen,
+ secret_new );
+ if( ret != 0 )
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+
+ mbedtls_platform_zeroize( tmp_secret, sizeof(tmp_secret) );
+ mbedtls_platform_zeroize( tmp_input, sizeof(tmp_input) );
+ return( ret );
+}
+
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/thirdparty/mbedtls/library/ssl_tls13_keys.h b/thirdparty/mbedtls/library/ssl_tls13_keys.h
new file mode 100644
index 0000000000..7089049ce2
--- /dev/null
+++ b/thirdparty/mbedtls/library/ssl_tls13_keys.h
@@ -0,0 +1,274 @@
+/*
+ * TLS 1.3 key schedule
+ *
+ * Copyright The Mbed TLS Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 ( the "License" ); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#if !defined(MBEDTLS_SSL_TLS1_3_KEYS_H)
+#define MBEDTLS_SSL_TLS1_3_KEYS_H
+
+/* This requires MBEDTLS_SSL_TLS1_3_LABEL( idx, name, string ) to be defined at
+ * the point of use. See e.g. the definition of mbedtls_ssl_tls1_3_labels_union
+ * below. */
+#define MBEDTLS_SSL_TLS1_3_LABEL_LIST \
+ MBEDTLS_SSL_TLS1_3_LABEL( finished , "finished" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( resumption , "resumption" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( traffic_upd , "traffic upd" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( exporter , "exporter" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( key , "key" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( iv , "iv" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_hs_traffic, "c hs traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_ap_traffic, "c ap traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( c_e_traffic , "c e traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_hs_traffic, "s hs traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_ap_traffic, "s ap traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( s_e_traffic , "s e traffic" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( e_exp_master, "e exp master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( res_master , "res master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( exp_master , "exp master" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( ext_binder , "ext binder" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( res_binder , "res binder" ) \
+ MBEDTLS_SSL_TLS1_3_LABEL( derived , "derived" )
+
+#define MBEDTLS_SSL_TLS1_3_LABEL( name, string ) \
+ const unsigned char name [ sizeof(string) - 1 ];
+
+union mbedtls_ssl_tls1_3_labels_union
+{
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+struct mbedtls_ssl_tls1_3_labels_struct
+{
+ MBEDTLS_SSL_TLS1_3_LABEL_LIST
+};
+#undef MBEDTLS_SSL_TLS1_3_LABEL
+
+extern const struct mbedtls_ssl_tls1_3_labels_struct mbedtls_ssl_tls1_3_labels;
+
+#define MBEDTLS_SSL_TLS1_3_LBL_WITH_LEN( LABEL ) \
+ mbedtls_ssl_tls1_3_labels.LABEL, \
+ sizeof(mbedtls_ssl_tls1_3_labels.LABEL)
+
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_LABEL_LEN \
+ sizeof( union mbedtls_ssl_tls1_3_labels_union )
+
+/* The maximum length of HKDF contexts used in the TLS 1.3 standard.
+ * Since contexts are always hashes of message transcripts, this can
+ * be approximated from above by the maximum hash size. */
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_CONTEXT_LEN \
+ MBEDTLS_MD_MAX_SIZE
+
+/* Maximum desired length for expanded key material generated
+ * by HKDF-Expand-Label.
+ *
+ * Warning: If this ever needs to be increased, the implementation
+ * ssl_tls1_3_hkdf_encode_label() in ssl_tls13_keys.c needs to be
+ * adjusted since it currently assumes that HKDF key expansion
+ * is never used with more than 255 Bytes of output. */
+#define MBEDTLS_SSL_TLS1_3_KEY_SCHEDULE_MAX_EXPANSION_LEN 255
+
+/**
+ * \brief The \c HKDF-Expand-Label function from
+ * the TLS 1.3 standard RFC 8446.
+ *
+ * <tt>
+ * HKDF-Expand-Label( Secret, Label, Context, Length ) =
+ * HKDF-Expand( Secret, HkdfLabel, Length )
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash algorithm to use.
+ * \param secret The \c Secret argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p slen Bytes.
+ * \param slen The length of \p secret in Bytes.
+ * \param label The \c Label argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p llen Bytes.
+ * \param llen The length of \p label in Bytes.
+ * \param ctx The \c Context argument to \c HKDF-Expand-Label.
+ * This must be a readable buffer of length \p clen Bytes.
+ * \param clen The length of \p context in Bytes.
+ * \param buf The destination buffer to hold the expanded secret.
+ * This must be a writable buffer of length \p blen Bytes.
+ * \param blen The desired size of the expanded secret in Bytes.
+ *
+ * \returns \c 0 on success.
+ * \return A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_hkdf_expand_label(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ unsigned char *buf, size_t blen );
+
+/**
+ * \brief This function is part of the TLS 1.3 key schedule.
+ * It extracts key and IV for the actual client/server traffic
+ * from the client/server traffic secrets.
+ *
+ * From RFC 8446:
+ *
+ * <tt>
+ * [sender]_write_key = HKDF-Expand-Label(Secret, "key", "", key_length)
+ * [sender]_write_iv = HKDF-Expand-Label(Secret, "iv", "", iv_length)*
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash algorithm to be used
+ * for the HKDF-based expansion of the secret.
+ * \param client_secret The client traffic secret.
+ * This must be a readable buffer of size \p slen Bytes
+ * \param server_secret The server traffic secret.
+ * This must be a readable buffer of size \p slen Bytes
+ * \param slen Length of the secrets \p client_secret and
+ * \p server_secret in Bytes.
+ * \param key_len The desired length of the key to be extracted in Bytes.
+ * \param iv_len The desired length of the IV to be extracted in Bytes.
+ * \param keys The address of the structure holding the generated
+ * keys and IVs.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_make_traffic_keys(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *client_secret,
+ const unsigned char *server_secret,
+ size_t slen, size_t key_len, size_t iv_len,
+ mbedtls_ssl_key_set *keys );
+
+
+#define MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED 0
+#define MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED 1
+
+/**
+ * \brief The \c Derive-Secret function from the TLS 1.3 standard RFC 8446.
+ *
+ * <tt>
+ * Derive-Secret( Secret, Label, Messages ) =
+ * HKDF-Expand-Label( Secret, Label,
+ * Hash( Messages ),
+ * Hash.Length ) )
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash function used for the
+ * applications of HKDF.
+ * \param secret The \c Secret argument to the \c Derive-Secret function.
+ * This must be a readable buffer of length \p slen Bytes.
+ * \param slen The length of \p secret in Bytes.
+ * \param label The \c Label argument to the \c Derive-Secret function.
+ * This must be a readable buffer of length \p llen Bytes.
+ * \param llen The length of \p label in Bytes.
+ * \param ctx The hash of the \c Messages argument to the
+ * \c Derive-Secret function, or the \c Messages argument
+ * itself, depending on \p context_already_hashed.
+ * \param clen The length of \p hash.
+ * \param ctx_hashed This indicates whether the \p ctx contains the hash of
+ * the \c Messages argument in the application of the
+ * \c Derive-Secret function
+ * (value MBEDTLS_SSL_TLS1_3_CONTEXT_HASHED), or whether
+ * it is the content of \c Messages itself, in which case
+ * the function takes care of the hashing
+ * (value MBEDTLS_SSL_TLS1_3_CONTEXT_UNHASHED).
+ * \param dstbuf The target buffer to write the output of
+ * \c Derive-Secret to. This must be a writable buffer of
+ * size \p buflen Bytes.
+ * \param buflen The length of \p dstbuf in Bytes.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+int mbedtls_ssl_tls1_3_derive_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret, size_t slen,
+ const unsigned char *label, size_t llen,
+ const unsigned char *ctx, size_t clen,
+ int ctx_hashed,
+ unsigned char *dstbuf, size_t buflen );
+
+/**
+ * \brief Compute the next secret in the TLS 1.3 key schedule
+ *
+ * The TLS 1.3 key schedule proceeds as follows to compute
+ * the three main secrets during the handshake: The early
+ * secret for early data, the handshake secret for all
+ * other encrypted handshake messages, and the master
+ * secret for all application traffic.
+ *
+ * <tt>
+ * 0
+ * |
+ * v
+ * PSK -> HKDF-Extract = Early Secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * (EC)DHE -> HKDF-Extract = Handshake Secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * 0 -> HKDF-Extract = Master Secret
+ * </tt>
+ *
+ * Each of the three secrets in turn is the basis for further
+ * key derivations, such as the derivation of traffic keys and IVs;
+ * see e.g. mbedtls_ssl_tls1_3_make_traffic_keys().
+ *
+ * This function implements one step in this evolution of secrets:
+ *
+ * <tt>
+ * old_secret
+ * |
+ * v
+ * Derive-Secret( ., "derived", "" )
+ * |
+ * v
+ * input -> HKDF-Extract = new_secret
+ * </tt>
+ *
+ * \param hash_alg The identifier for the hash function used for the
+ * applications of HKDF.
+ * \param secret_old The address of the buffer holding the old secret
+ * on function entry. If not \c NULL, this must be a
+ * readable buffer whose size matches the output size
+ * of the hash function represented by \p hash_alg.
+ * If \c NULL, an all \c 0 array will be used instead.
+ * \param input The address of the buffer holding the additional
+ * input for the key derivation (e.g., the PSK or the
+ * ephemeral (EC)DH secret). If not \c NULL, this must be
+ * a readable buffer whose size \p input_len Bytes.
+ * If \c NULL, an all \c 0 array will be used instead.
+ * \param input_len The length of \p input in Bytes.
+ * \param secret_new The address of the buffer holding the new secret
+ * on function exit. This must be a writable buffer
+ * whose size matches the output size of the hash
+ * function represented by \p hash_alg.
+ * This may be the same as \p secret_old.
+ *
+ * \returns \c 0 on success.
+ * \returns A negative error code on failure.
+ */
+
+int mbedtls_ssl_tls1_3_evolve_secret(
+ mbedtls_md_type_t hash_alg,
+ const unsigned char *secret_old,
+ const unsigned char *input, size_t input_len,
+ unsigned char *secret_new );
+
+#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */
diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c
index 0dc5488c1a..2de117f52a 100644
--- a/thirdparty/mbedtls/library/threading.c
+++ b/thirdparty/mbedtls/library/threading.c
@@ -2,13 +2,7 @@
* Threading abstraction layer
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
@@ -52,11 +25,7 @@
#define _POSIX_C_SOURCE 200112L
#endif
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_THREADING_C)
@@ -102,8 +71,8 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
* mutex. This is a workaround for not being able to return an error
* code for this function. The lock/unlock functions return an error
* if is_valid is nonzero. The Mbed TLS unit test code uses this field
- * to distinguish more states of the mutex; see helpers.function for
- * details. */
+ * to distinguish more states of the mutex; see
+ * tests/src/threading_helpers for details. */
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
}
diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c
index 50a22165a6..eb41461320 100644
--- a/thirdparty/mbedtls/library/timing.c
+++ b/thirdparty/mbedtls/library/timing.c
@@ -2,13 +2,7 @@
* Portable interface to the CPU cycle counter
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
@@ -65,7 +34,7 @@
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \
- !defined(__HAIKU__)
+ !defined(__HAIKU__) && !defined(__midipix__)
#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h"
#endif
diff --git a/thirdparty/mbedtls/library/version.c b/thirdparty/mbedtls/library/version.c
index 5733288f62..32a0d7d584 100644
--- a/thirdparty/mbedtls/library/version.c
+++ b/thirdparty/mbedtls/library/version.c
@@ -2,13 +2,7 @@
* Version information
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c
index 8c8e815e9d..40c95201bc 100644
--- a/thirdparty/mbedtls/library/version_features.c
+++ b/thirdparty/mbedtls/library/version_features.c
@@ -2,13 +2,7 @@
* Version feature information
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_VERSION_C)
@@ -56,7 +25,7 @@
#include <string.h>
-static const char *features[] = {
+static const char * const features[] = {
#if defined(MBEDTLS_VERSION_FEATURES)
#if defined(MBEDTLS_HAVE_ASM)
"MBEDTLS_HAVE_ASM",
@@ -97,6 +66,9 @@ static const char *features[] = {
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
"MBEDTLS_PLATFORM_SNPRINTF_ALT",
#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */
+#if defined(MBEDTLS_PLATFORM_VSNPRINTF_ALT)
+ "MBEDTLS_PLATFORM_VSNPRINTF_ALT",
+#endif /* MBEDTLS_PLATFORM_VSNPRINTF_ALT */
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
"MBEDTLS_PLATFORM_NV_SEED_ALT",
#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */
@@ -253,6 +225,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
"MBEDTLS_ECP_INTERNAL_ALT",
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+#if defined(MBEDTLS_ECP_NO_FALLBACK)
+ "MBEDTLS_ECP_NO_FALLBACK",
+#endif /* MBEDTLS_ECP_NO_FALLBACK */
#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT)
"MBEDTLS_ECP_RANDOMIZE_JAC_ALT",
#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */
@@ -277,12 +252,6 @@ 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 */
@@ -298,6 +267,9 @@ static const char *features[] = {
#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
"MBEDTLS_CAMELLIA_SMALL_MEMORY",
#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
+#if defined(MBEDTLS_CHECK_RETURN_WARNING)
+ "MBEDTLS_CHECK_RETURN_WARNING",
+#endif /* MBEDTLS_CHECK_RETURN_WARNING */
#if defined(MBEDTLS_CIPHER_MODE_CBC)
"MBEDTLS_CIPHER_MODE_CBC",
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -388,6 +360,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECP_RESTARTABLE)
"MBEDTLS_ECP_RESTARTABLE",
#endif /* MBEDTLS_ECP_RESTARTABLE */
+#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT)
+ "MBEDTLS_ECDH_LEGACY_CONTEXT",
+#endif /* MBEDTLS_ECDH_LEGACY_CONTEXT */
#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
"MBEDTLS_ECDSA_DETERMINISTIC",
#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
@@ -448,6 +423,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ENTROPY_NV_SEED)
"MBEDTLS_ENTROPY_NV_SEED",
#endif /* MBEDTLS_ENTROPY_NV_SEED */
+#if defined(MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER)
+ "MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER",
+#endif /* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER */
#if defined(MBEDTLS_MEMORY_DEBUG)
"MBEDTLS_MEMORY_DEBUG",
#endif /* MBEDTLS_MEMORY_DEBUG */
@@ -463,6 +441,24 @@ static const char *features[] = {
#if defined(MBEDTLS_PKCS1_V21)
"MBEDTLS_PKCS1_V21",
#endif /* MBEDTLS_PKCS1_V21 */
+#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)
+ "MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS",
+#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */
+#if defined(MBEDTLS_PSA_CRYPTO_CLIENT)
+ "MBEDTLS_PSA_CRYPTO_CLIENT",
+#endif /* MBEDTLS_PSA_CRYPTO_CLIENT */
+#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS)
+ "MBEDTLS_PSA_CRYPTO_DRIVERS",
+#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */
+#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
+ "MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG",
+#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
+#if defined(MBEDTLS_PSA_CRYPTO_SPM)
+ "MBEDTLS_PSA_CRYPTO_SPM",
+#endif /* MBEDTLS_PSA_CRYPTO_SPM */
+#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
+ "MBEDTLS_PSA_INJECT_ENTROPY",
+#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
#if defined(MBEDTLS_RSA_NO_CRT)
"MBEDTLS_RSA_NO_CRT",
#endif /* MBEDTLS_RSA_NO_CRT */
@@ -472,12 +468,27 @@ static const char *features[] = {
#if defined(MBEDTLS_SHA256_SMALLER)
"MBEDTLS_SHA256_SMALLER",
#endif /* MBEDTLS_SHA256_SMALLER */
+#if defined(MBEDTLS_SHA512_SMALLER)
+ "MBEDTLS_SHA512_SMALLER",
+#endif /* MBEDTLS_SHA512_SMALLER */
+#if defined(MBEDTLS_SHA512_NO_SHA384)
+ "MBEDTLS_SHA512_NO_SHA384",
+#endif /* MBEDTLS_SHA512_NO_SHA384 */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
+#if defined(MBEDTLS_SSL_RECORD_CHECKING)
+ "MBEDTLS_SSL_RECORD_CHECKING",
+#endif /* MBEDTLS_SSL_RECORD_CHECKING */
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ "MBEDTLS_SSL_DTLS_CONNECTION_ID",
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
"MBEDTLS_SSL_ASYNC_PRIVATE",
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
+#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
+ "MBEDTLS_SSL_CONTEXT_SERIALIZATION",
+#endif /* MBEDTLS_SSL_CONTEXT_SERIALIZATION */
#if defined(MBEDTLS_SSL_DEBUG_ALL)
"MBEDTLS_SSL_DEBUG_ALL",
#endif /* MBEDTLS_SSL_DEBUG_ALL */
@@ -490,6 +501,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
"MBEDTLS_SSL_FALLBACK_SCSV",
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
+#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE",
+#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
"MBEDTLS_SSL_HW_RECORD_ACCEL",
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
@@ -520,6 +534,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
"MBEDTLS_SSL_PROTO_TLS1_2",
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL)
+ "MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL",
+#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
"MBEDTLS_SSL_PROTO_DTLS",
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -532,6 +549,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
"MBEDTLS_SSL_DTLS_HELLO_VERIFY",
#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */
+#if defined(MBEDTLS_SSL_DTLS_SRTP)
+ "MBEDTLS_SSL_DTLS_SRTP",
+#endif /* MBEDTLS_SSL_DTLS_SRTP */
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE)
"MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE",
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */
@@ -553,6 +573,15 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH",
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
+#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_HOOKS)
"MBEDTLS_TEST_HOOKS",
#endif /* MBEDTLS_TEST_HOOKS */
@@ -562,6 +591,12 @@ static const char *features[] = {
#if defined(MBEDTLS_THREADING_PTHREAD)
"MBEDTLS_THREADING_PTHREAD",
#endif /* MBEDTLS_THREADING_PTHREAD */
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ "MBEDTLS_USE_PSA_CRYPTO",
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
+#if defined(MBEDTLS_PSA_CRYPTO_CONFIG)
+ "MBEDTLS_PSA_CRYPTO_CONFIG",
+#endif /* MBEDTLS_PSA_CRYPTO_CONFIG */
#if defined(MBEDTLS_VERSION_FEATURES)
"MBEDTLS_VERSION_FEATURES",
#endif /* MBEDTLS_VERSION_FEATURES */
@@ -571,6 +606,9 @@ static const char *features[] = {
#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
"MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION",
#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ "MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK",
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
"MBEDTLS_X509_CHECK_KEY_USAGE",
#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */
@@ -730,6 +768,18 @@ static const char *features[] = {
#if defined(MBEDTLS_POLY1305_C)
"MBEDTLS_POLY1305_C",
#endif /* MBEDTLS_POLY1305_C */
+#if defined(MBEDTLS_PSA_CRYPTO_C)
+ "MBEDTLS_PSA_CRYPTO_C",
+#endif /* MBEDTLS_PSA_CRYPTO_C */
+#if defined(MBEDTLS_PSA_CRYPTO_SE_C)
+ "MBEDTLS_PSA_CRYPTO_SE_C",
+#endif /* MBEDTLS_PSA_CRYPTO_SE_C */
+#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
+ "MBEDTLS_PSA_CRYPTO_STORAGE_C",
+#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
+#if defined(MBEDTLS_PSA_ITS_FILE_C)
+ "MBEDTLS_PSA_ITS_FILE_C",
+#endif /* MBEDTLS_PSA_ITS_FILE_C */
#if defined(MBEDTLS_RIPEMD160_C)
"MBEDTLS_RIPEMD160_C",
#endif /* MBEDTLS_RIPEMD160_C */
@@ -802,7 +852,7 @@ static const char *features[] = {
int mbedtls_version_check_feature( const char *feature )
{
- const char **idx = features;
+ const char * const *idx = features;
if( *idx == NULL )
return( -2 );
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index 0c820eca90..f21e9e6944 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -2,13 +2,7 @@
* X.509 common functions for parsing and verification
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,16 +27,13 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_USE_C)
#include "mbedtls/x509.h"
#include "mbedtls/asn1.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include <stdio.h>
@@ -108,21 +78,21 @@
int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
**p != MBEDTLS_ASN1_INTEGER )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
serial->tag = *(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SERIAL, ret ) );
serial->p = *p;
*p += serial->len;
@@ -139,10 +109,10 @@ int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
return( 0 );
}
@@ -153,10 +123,10 @@ int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
return( 0 );
}
@@ -173,7 +143,7 @@ int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
*/
static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
const unsigned char *end;
mbedtls_x509_buf md_oid;
@@ -181,39 +151,39 @@ static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md
/* Make sure we got a SEQUENCE and setup bounds */
if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
- p = (unsigned char *) alg->p;
+ p = alg->p;
end = p + alg->len;
if( p >= end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
/* Parse md_oid */
md_oid.tag = *p;
if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
md_oid.p = p;
p += md_oid.len;
/* Get md_alg from md_oid */
if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
/* Make sure params is absent of NULL */
if( p == end )
return( 0 );
if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -234,7 +204,7 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
int *salt_len )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char *p;
const unsigned char *end, *end2;
size_t len;
@@ -247,8 +217,8 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
/* Make sure params is a SEQUENCE and setup bounds */
if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
p = (unsigned char *) params->p;
end = p + params->len;
@@ -269,14 +239,14 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
return( ret );
if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -295,19 +265,19 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
/* Only MFG1 is recognised for now */
if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
- MBEDTLS_ERR_OID_NOT_FOUND );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
+ MBEDTLS_ERR_OID_NOT_FOUND ) );
/* Parse HashAlgorithm */
if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
return( ret );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -321,14 +291,14 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p == end )
return( 0 );
@@ -344,21 +314,21 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
end2 = p + len;
if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end2 )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
if( trailer_field != 1 )
return( MBEDTLS_ERR_X509_INVALID_ALG );
}
else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
- return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG, ret ) );
if( p != end )
- return( MBEDTLS_ERR_X509_INVALID_ALG +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_ALG,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -377,54 +347,54 @@ static int x509_get_attr_type_value( unsigned char **p,
const unsigned char *end,
mbedtls_x509_name *cur )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
mbedtls_x509_buf *oid;
mbedtls_x509_buf *val;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
end = *p + len;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
oid = &cur->oid;
oid->tag = **p;
if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
oid->p = *p;
*p += oid->len;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
**p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
**p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
**p != MBEDTLS_ASN1_BIT_STRING )
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
val = &cur->val;
val->tag = *(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
val->p = *p;
*p += val->len;
if( *p != end )
{
- return( MBEDTLS_ERR_X509_INVALID_NAME +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
cur->next = NULL;
@@ -458,7 +428,7 @@ static int x509_get_attr_type_value( unsigned char **p,
int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
mbedtls_x509_name *cur )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t set_len;
const unsigned char *end_set;
@@ -470,7 +440,7 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
*/
if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_NAME, ret ) );
end_set = *p + set_len;
@@ -564,7 +534,7 @@ static int x509_date_is_valid(const mbedtls_x509_time *t )
static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
mbedtls_x509_time *tm )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/*
* Minimum length is 10 or 12 depending on yearlen
@@ -629,13 +599,13 @@ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
mbedtls_x509_time *tm )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len, year_len;
unsigned char tag;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
tag = **p;
@@ -644,32 +614,32 @@ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
year_len = 4;
else
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
(*p)++;
ret = mbedtls_asn1_get_len( p, end, &len );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, ret ) );
return x509_parse_time( p, len, year_len, tm );
}
int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
int tag_type;
if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) );
tag_type = **p;
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret ) );
sig->tag = tag_type;
sig->len = len;
@@ -687,13 +657,13 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
void **sig_opts )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *sig_opts != NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
- return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret ) );
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
@@ -735,7 +705,7 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50
int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
mbedtls_x509_buf *ext, int tag )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/* Extension structure use EXPLICIT tagging. That is, the actual
@@ -744,7 +714,7 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
ret = mbedtls_asn1_get_tag( p, end, &ext->len,
MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
ext->p = *p;
@@ -755,11 +725,11 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
*/
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( end != *p + len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -770,7 +740,7 @@ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
*/
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n;
unsigned char c, merge = 0;
const mbedtls_x509_name *name;
@@ -811,7 +781,7 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
break;
c = name->val.p[i];
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
+ if( c < 32 || c >= 127 )
s[i] = '?';
else s[i] = c;
}
@@ -832,7 +802,7 @@ int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
*/
int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i, n, nr;
char *p;
@@ -868,7 +838,7 @@ int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *s
mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
const void *sig_opts )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
char *p = buf;
size_t n = size;
const char *desc = NULL;
@@ -894,7 +864,7 @@ int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *s
ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
md_info ? mbedtls_md_get_name( md_info ) : "???",
mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
- pss_opts->expected_salt_len );
+ (unsigned int) pss_opts->expected_salt_len );
MBEDTLS_X509_SAFE_SNPRINTF;
}
#else
@@ -913,7 +883,7 @@ int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
{
char *p = buf;
size_t n = buf_size;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
ret = mbedtls_snprintf( p, n, "%s key size", name );
MBEDTLS_X509_SAFE_SNPRINTF;
diff --git a/thirdparty/mbedtls/library/x509_create.c b/thirdparty/mbedtls/library/x509_create.c
index 0dbd679a93..056bbaa786 100644
--- a/thirdparty/mbedtls/library/x509_create.c
+++ b/thirdparty/mbedtls/library/x509_create.c
@@ -2,13 +2,7 @@
* X.509 base functions for creating certificates / CSRs
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,39 +15,15 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CREATE_C)
#include "mbedtls/x509.h"
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include <string.h>
@@ -266,7 +236,7 @@ int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid,
*/
static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn1_named_data* cur_name)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
const char *oid = (const char*)cur_name->oid.p;
size_t oid_len = cur_name->oid.len;
@@ -299,7 +269,7 @@ static int x509_write_name( unsigned char **p, unsigned char *start, mbedtls_asn
int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_asn1_named_data *cur = first;
@@ -320,7 +290,7 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
const char *oid, size_t oid_len,
unsigned char *sig, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
if( *p < start || (size_t)( *p - start ) < size )
@@ -350,7 +320,7 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
static int x509_write_extension( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1,
@@ -388,7 +358,7 @@ static int x509_write_extension( unsigned char **p, unsigned char *start,
int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
mbedtls_asn1_named_data *first )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
mbedtls_asn1_named_data *cur_ext = first;
diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c
index dba71fad58..ac4fc75de3 100644
--- a/thirdparty/mbedtls/library/x509_crl.c
+++ b/thirdparty/mbedtls/library/x509_crl.c
@@ -2,13 +2,7 @@
* X.509 Certidicate Revocation List (CRL) parsing
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,15 +27,12 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRL_PARSE_C)
#include "mbedtls/x509_crl.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -99,7 +69,7 @@ static int x509_crl_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
{
@@ -109,7 +79,7 @@ static int x509_crl_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
}
return( 0 );
@@ -126,7 +96,7 @@ static int x509_get_crl_ext( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *p == end )
return( 0 );
@@ -155,7 +125,7 @@ static int x509_get_crl_ext( unsigned char **p,
/* Get enclosing sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
end_ext_data = *p + len;
@@ -163,7 +133,7 @@ static int x509_get_crl_ext( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OID ) ) != 0 )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
*p += len;
@@ -172,29 +142,29 @@ static int x509_get_crl_ext( unsigned char **p,
&is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
/* Data should be octet string type */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Ignore data so far and just check its length */
*p += len;
if( *p != end_ext_data )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Abort on (unsupported) critical extensions */
if( is_critical )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -206,7 +176,7 @@ static int x509_get_crl_entry_ext( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *ext )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/* OPTIONAL */
@@ -228,27 +198,27 @@ static int x509_get_crl_entry_ext( unsigned char **p,
ext->p = NULL;
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
}
end = *p + ext->len;
if( end != *p + ext->len )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
while( *p < end )
{
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
*p += len;
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -260,7 +230,7 @@ static int x509_get_entries( unsigned char **p,
const unsigned char *end,
mbedtls_x509_crl_entry *entry )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t entry_len;
mbedtls_x509_crl_entry *cur_entry = entry;
@@ -325,7 +295,7 @@ static int x509_get_entries( unsigned char **p,
int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p = NULL, *end = NULL;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
@@ -394,8 +364,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( len != (size_t) ( end - p ) )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
/*
@@ -407,7 +377,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -451,7 +421,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
@@ -474,10 +444,10 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 )
{
- if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) &&
- ret != ( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA ) )
+ if( ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) &&
+ ret != ( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ) )
{
mbedtls_x509_crl_free( crl );
return( ret );
@@ -516,8 +486,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( p != end )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
end = crl->raw.p + crl->raw.len;
@@ -551,8 +521,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
if( p != end )
{
mbedtls_x509_crl_free( crl );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -564,8 +534,8 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain,
int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
- int ret;
- size_t use_len;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ size_t use_len = 0;
mbedtls_pem_context pem;
int is_pem = 0;
@@ -628,7 +598,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s
*/
int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -655,7 +625,7 @@ int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path )
int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_crl *crl )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
const mbedtls_x509_crl_entry *entry;
diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c
index 52f6de8fc0..60312bf2f5 100644
--- a/thirdparty/mbedtls/library/x509_crt.c
+++ b/thirdparty/mbedtls/library/x509_crt.c
@@ -2,13 +2,7 @@
* X.509 certificate parsing and verification
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -56,15 +29,12 @@
* [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/x509_crt.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -74,6 +44,11 @@
#include "mbedtls/pem.h"
#endif
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -133,10 +108,6 @@ typedef struct {
* concerns. */
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
{
-#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
- /* Allow SHA-1 (weak, but still safe in controlled environments) */
- MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
-#endif
/* Only SHA-2 hashes */
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
@@ -409,6 +380,10 @@ static void x509_crt_verify_chain_reset(
}
ver_chain->len = 0;
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ ver_chain->trust_ca_cb_result = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
}
/*
@@ -418,7 +393,7 @@ static int x509_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
@@ -430,17 +405,17 @@ static int x509_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = *p + len;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_VERSION +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -455,12 +430,12 @@ static int x509_get_dates( unsigned char **p,
mbedtls_x509_time *from,
mbedtls_x509_time *to )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE, ret ) );
end = *p + len;
@@ -471,8 +446,8 @@ static int x509_get_dates( unsigned char **p,
return( ret );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_DATE +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_DATE,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -484,7 +459,7 @@ static int x509_get_uid( unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *uid, int n )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( *p == end )
return( 0 );
@@ -497,7 +472,7 @@ static int x509_get_uid( unsigned char **p,
if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
return( 0 );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
uid->p = *p;
@@ -511,7 +486,7 @@ static int x509_get_basic_constraints( unsigned char **p,
int *ca_istrue,
int *max_pathlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
/*
@@ -524,7 +499,7 @@ static int x509_get_basic_constraints( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p == end )
return( 0 );
@@ -535,7 +510,7 @@ static int x509_get_basic_constraints( unsigned char **p,
ret = mbedtls_asn1_get_int( p, end, ca_istrue );
if( ret != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *ca_istrue != 0 )
*ca_istrue = 1;
@@ -545,17 +520,17 @@ static int x509_get_basic_constraints( unsigned char **p,
return( 0 );
if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
* overflow, which is an undefined behavior. */
if( *max_pathlen == INT_MAX )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
(*max_pathlen)++;
@@ -566,15 +541,15 @@ static int x509_get_ns_cert_type( unsigned char **p,
const unsigned char *end,
unsigned char *ns_cert_type)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_bitstring bs = { 0, 0, NULL };
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( bs.len != 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
/* Get actual bitstring */
*ns_cert_type = *bs.p;
@@ -585,16 +560,16 @@ static int x509_get_key_usage( unsigned char **p,
const unsigned char *end,
unsigned int *key_usage)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t i;
mbedtls_x509_bitstring bs = { 0, 0, NULL };
if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( bs.len < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
/* Get actual bitstring */
*key_usage = 0;
@@ -615,15 +590,15 @@ static int x509_get_ext_key_usage( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *ext_key_usage)
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Sequence length must be >= 1 */
if( ext_key_usage->buf.p == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_INVALID_LENGTH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_INVALID_LENGTH ) );
return( 0 );
}
@@ -652,13 +627,14 @@ static int x509_get_ext_key_usage( unsigned char **p,
* nameAssigner [0] DirectoryString OPTIONAL,
* partyName [1] DirectoryString }
*
- * NOTE: we only parse and use dNSName at this point.
+ * NOTE: we list all types, but only use dNSName and otherName
+ * of type HwModuleName, as defined in RFC 4108, at this point.
*/
static int x509_get_subject_alt_name( unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *subject_alt_name )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len, tag_len;
mbedtls_asn1_buf *buf;
unsigned char tag;
@@ -667,35 +643,51 @@ static int x509_get_subject_alt_name( unsigned char **p,
/* Get main sequence tag */
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( *p + len != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
while( *p < end )
{
- if( ( end - *p ) < 1 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_OUT_OF_DATA );
+ mbedtls_x509_subject_alternative_name dummy_san_buf;
+ memset( &dummy_san_buf, 0, sizeof( dummy_san_buf ) );
tag = **p;
(*p)++;
if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) !=
MBEDTLS_ASN1_CONTEXT_SPECIFIC )
{
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
- /* Skip everything but DNS name */
- if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
+ /*
+ * Check that the SAN is structured correctly.
+ */
+ ret = mbedtls_x509_parse_subject_alt_name( &(cur->buf), &dummy_san_buf );
+ /*
+ * In case the extension is malformed, return an error,
+ * and clear the allocated sequences.
+ */
+ if( ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
{
- *p += tag_len;
- continue;
+ mbedtls_x509_sequence *seq_cur = subject_alt_name->next;
+ mbedtls_x509_sequence *seq_prv;
+ while( seq_cur != NULL )
+ {
+ seq_prv = seq_cur;
+ seq_cur = seq_cur->next;
+ mbedtls_platform_zeroize( seq_prv,
+ sizeof( mbedtls_x509_sequence ) );
+ mbedtls_free( seq_prv );
+ }
+ subject_alt_name->next = NULL;
+ return( ret );
}
/* Allocate and assign next pointer */
@@ -707,8 +699,8 @@ static int x509_get_subject_alt_name( unsigned char **p,
cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
if( cur->next == NULL )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_ALLOC_FAILED );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_ALLOC_FAILED ) );
cur = cur->next;
}
@@ -724,23 +716,187 @@ static int x509_get_subject_alt_name( unsigned char **p,
cur->next = NULL;
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
/*
+ * id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ *
+ * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
+ *
+ * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
+ *
+ * PolicyInformation ::= SEQUENCE {
+ * policyIdentifier CertPolicyId,
+ * policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ * PolicyQualifierInfo OPTIONAL }
+ *
+ * CertPolicyId ::= OBJECT IDENTIFIER
+ *
+ * PolicyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ *
+ * -- policyQualifierIds for Internet policy qualifiers
+ *
+ * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ *
+ * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ *
+ * Qualifier ::= CHOICE {
+ * cPSuri CPSuri,
+ * userNotice UserNotice }
+ *
+ * CPSuri ::= IA5String
+ *
+ * UserNotice ::= SEQUENCE {
+ * noticeRef NoticeReference OPTIONAL,
+ * explicitText DisplayText OPTIONAL }
+ *
+ * NoticeReference ::= SEQUENCE {
+ * organization DisplayText,
+ * noticeNumbers SEQUENCE OF INTEGER }
+ *
+ * DisplayText ::= CHOICE {
+ * ia5String IA5String (SIZE (1..200)),
+ * visibleString VisibleString (SIZE (1..200)),
+ * bmpString BMPString (SIZE (1..200)),
+ * utf8String UTF8String (SIZE (1..200)) }
+ *
+ * NOTE: we only parse and use anyPolicy without qualifiers at this point
+ * as defined in RFC 5280.
+ */
+static int x509_get_certificate_policies( unsigned char **p,
+ const unsigned char *end,
+ mbedtls_x509_sequence *certificate_policies )
+{
+ int ret, parse_ret = 0;
+ size_t len;
+ mbedtls_asn1_buf *buf;
+ mbedtls_asn1_sequence *cur = certificate_policies;
+
+ /* Get main sequence tag */
+ ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE );
+ if( ret != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( *p + len != end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ /*
+ * Cannot be an empty sequence.
+ */
+ if( len == 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ while( *p < end )
+ {
+ mbedtls_x509_buf policy_oid;
+ const unsigned char *policy_end;
+
+ /*
+ * Get the policy sequence
+ */
+ if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ policy_end = *p + len;
+
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ policy_oid.tag = MBEDTLS_ASN1_OID;
+ policy_oid.len = len;
+ policy_oid.p = *p;
+
+ /*
+ * Only AnyPolicy is currently supported when enforcing policy.
+ */
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_POLICY, &policy_oid ) != 0 )
+ {
+ /*
+ * Set the parsing return code but continue parsing, in case this
+ * extension is critical and MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ * is configured.
+ */
+ parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
+ }
+
+ /* Allocate and assign next pointer */
+ if( cur->buf.p != NULL )
+ {
+ if( cur->next != NULL )
+ return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
+
+ cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
+
+ if( cur->next == NULL )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_ALLOC_FAILED ) );
+
+ cur = cur->next;
+ }
+
+ buf = &( cur->buf );
+ buf->tag = policy_oid.tag;
+ buf->p = policy_oid.p;
+ buf->len = policy_oid.len;
+
+ *p += len;
+
+ /*
+ * If there is an optional qualifier, then *p < policy_end
+ * Check the Qualifier len to verify it doesn't exceed policy_end.
+ */
+ if( *p < policy_end )
+ {
+ if( ( ret = mbedtls_asn1_get_tag( p, policy_end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+ /*
+ * Skip the optional policy qualifiers.
+ */
+ *p += len;
+ }
+
+ if( *p != policy_end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+
+ /* Set final sequence entry's next pointer to NULL */
+ cur->next = NULL;
+
+ if( *p != end )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+
+ return( parse_ret );
+}
+
+/*
* X.509 v3 extensions
*
*/
static int x509_get_crt_ext( unsigned char **p,
const unsigned char *end,
- mbedtls_x509_crt *crt )
+ mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
- unsigned char *end_ext_data, *end_ext_octet;
+ unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
if( *p == end )
return( 0 );
@@ -763,14 +919,14 @@ static int x509_get_crt_ext( unsigned char **p,
if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
end_ext_data = *p + len;
/* Get extension ID */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
MBEDTLS_ASN1_OID ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
extn_oid.tag = MBEDTLS_ASN1_OID;
extn_oid.p = *p;
@@ -779,18 +935,19 @@ static int x509_get_crt_ext( unsigned char **p,
/* Get optional critical */
if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
/* Data should be octet string type */
if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+ start_ext_octet = *p;
end_ext_octet = *p + len;
if( end_ext_octet != end_ext_data )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
/*
* Detect supported extensions
@@ -799,6 +956,16 @@ static int x509_get_crt_ext( unsigned char **p,
if( ret != 0 )
{
+ /* Give the callback (if any) a chance to handle the extension */
+ if( cb != NULL )
+ {
+ ret = cb( p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet );
+ if( ret != 0 && is_critical )
+ return( ret );
+ *p = end_ext_octet;
+ continue;
+ }
+
/* No parser found, skip extension */
*p = end_ext_octet;
@@ -806,8 +973,8 @@ static int x509_get_crt_ext( unsigned char **p,
if( is_critical )
{
/* Data is marked as critical: fail */
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) );
}
#endif
continue;
@@ -856,14 +1023,52 @@ static int x509_get_crt_ext( unsigned char **p,
return( ret );
break;
+ case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES:
+ /* Parse certificate policies type */
+ if( ( ret = x509_get_certificate_policies( p, end_ext_octet,
+ &crt->certificate_policies ) ) != 0 )
+ {
+ /* Give the callback (if any) a chance to handle the extension
+ * if it contains unsupported policies */
+ if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL &&
+ cb( p_ctx, crt, &extn_oid, is_critical,
+ start_ext_octet, end_ext_octet ) == 0 )
+ break;
+
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+ if( is_critical )
+ return( ret );
+ else
+#endif
+ /*
+ * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we
+ * cannot interpret or enforce the policy. However, it is up to
+ * the user to choose how to enforce the policies,
+ * unless the extension is critical.
+ */
+ if( ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
+ return( ret );
+ }
+ break;
+
default:
- return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ /*
+ * If this is a non-critical extension, which the oid layer
+ * supports, but there isn't an x509 parser for it,
+ * skip the extension.
+ */
+#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
+ if( is_critical )
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ else
+#endif
+ *p = end_ext_octet;
}
}
if( *p != end )
- return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
return( 0 );
}
@@ -871,10 +1076,14 @@ static int x509_get_crt_ext( unsigned char **p,
/*
* Parse and fill a single X.509 certificate in DER format
*/
-static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
- size_t buflen )
+static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end, *crt_end;
mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
@@ -889,7 +1098,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- // Use the original buffer until we figure out actual length
+ /* Use the original buffer until we figure out actual length. */
p = (unsigned char*) buf;
len = buflen;
end = p + len;
@@ -907,25 +1116,26 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
}
- if( len > (size_t) ( end - p ) )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- crt_end = p + len;
-
- // Create and populate a new buffer for the raw field
+ end = crt_end = p + len;
crt->raw.len = crt_end - buf;
- crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
- if( p == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+ if( make_copy != 0 )
+ {
+ /* Create and populate a new buffer for the raw field. */
+ crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
+ if( crt->raw.p == NULL )
+ return( MBEDTLS_ERR_X509_ALLOC_FAILED );
- memcpy( p, buf, crt->raw.len );
+ memcpy( crt->raw.p, buf, crt->raw.len );
+ crt->own_buffer = 1;
- // Direct pointers to the new buffer
- p += crt->raw.len - len;
- end = crt_end = p + len;
+ p += crt->raw.len - len;
+ end = crt_end = p + len;
+ }
+ else
+ {
+ crt->raw.p = (unsigned char*) buf;
+ crt->own_buffer = 0;
+ }
/*
* TBSCertificate ::= SEQUENCE {
@@ -936,7 +1146,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -983,7 +1193,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
@@ -1016,7 +1226,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
@@ -1030,11 +1240,13 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
/*
* SubjectPublicKeyInfo
*/
+ crt->pk_raw.p = p;
if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
return( ret );
}
+ crt->pk_raw.len = p - crt->pk_raw.p;
/*
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
@@ -1068,7 +1280,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt->version == 3 )
#endif
{
- ret = x509_get_crt_ext( &p, end, crt );
+ ret = x509_get_crt_ext( &p, end, crt, cb, p_ctx );
if( ret != 0 )
{
mbedtls_x509_crt_free( crt );
@@ -1079,8 +1291,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( p != end )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
end = crt_end;
@@ -1118,8 +1330,8 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( p != end )
{
mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -1129,10 +1341,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
* Parse one X.509 certificate in DER format from a buffer and add them to a
* chained list
*/
-int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen )
+static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *crt = chain, *prev = NULL;
/*
@@ -1162,7 +1378,8 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
crt = crt->next;
}
- if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
+ ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy, cb, p_ctx );
+ if( ret != 0 )
{
if( prev )
prev->next = NULL;
@@ -1176,11 +1393,37 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu
return( 0 );
}
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0, NULL, NULL ) );
+}
+
+int mbedtls_x509_crt_parse_der_with_ext_cb( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy,
+ mbedtls_x509_crt_ext_cb_t cb,
+ void *p_ctx )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, make_copy, cb, p_ctx ) );
+}
+
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1, NULL, NULL ) );
+}
+
/*
* Parse one or more PEM certificates from a buffer and add them to the chained
* list
*/
-int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
int success = 0, first_error = 0, total_failed = 0;
@@ -1213,7 +1456,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
#if defined(MBEDTLS_PEM_PARSE_C)
if( buf_format == MBEDTLS_X509_FORMAT_PEM )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pem_context pem;
/* 1 rather than 0 since the terminating NULL byte is counted in */
@@ -1297,7 +1540,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
*/
int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -1409,6 +1652,8 @@ cleanup:
}
#endif /* MBEDTLS_THREADING_C */
+ memset( &sb, 0, sizeof( sb ) );
+
while( ( entry = readdir( dir ) ) != NULL )
{
snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
@@ -1451,32 +1696,201 @@ cleanup:
}
#endif /* MBEDTLS_FS_IO */
+/*
+ * OtherName ::= SEQUENCE {
+ * type-id OBJECT IDENTIFIER,
+ * value [0] EXPLICIT ANY DEFINED BY type-id }
+ *
+ * HardwareModuleName ::= SEQUENCE {
+ * hwType OBJECT IDENTIFIER,
+ * hwSerialNum OCTET STRING }
+ *
+ * NOTE: we currently only parse and use otherName of type HwModuleName,
+ * as defined in RFC 4108.
+ */
+static int x509_get_other_name( const mbedtls_x509_buf *subject_alt_name,
+ mbedtls_x509_san_other_name *other_name )
+{
+ int ret = 0;
+ size_t len;
+ unsigned char *p = subject_alt_name->p;
+ const unsigned char *end = p + subject_alt_name->len;
+ mbedtls_x509_buf cur_oid;
+
+ if( ( subject_alt_name->tag &
+ ( MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK ) ) !=
+ ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ) )
+ {
+ /*
+ * The given subject alternative name is not of type "othername".
+ */
+ return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
+ }
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ cur_oid.tag = MBEDTLS_ASN1_OID;
+ cur_oid.p = p;
+ cur_oid.len = len;
+
+ /*
+ * Only HwModuleName is currently supported.
+ */
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid ) != 0 )
+ {
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ p += len;
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OID ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
+ other_name->value.hardware_module_name.oid.p = p;
+ other_name->value.hardware_module_name.oid.len = len;
+
+ if( p + len >= end )
+ {
+ mbedtls_platform_zeroize( other_name, sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ p += len;
+ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+ MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret ) );
+
+ other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
+ other_name->value.hardware_module_name.val.p = p;
+ other_name->value.hardware_module_name.val.len = len;
+ p += len;
+ if( p != end )
+ {
+ mbedtls_platform_zeroize( other_name,
+ sizeof( *other_name ) );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
+ }
+ return( 0 );
+}
+
static int x509_info_subject_alt_name( char **buf, size_t *size,
- const mbedtls_x509_sequence *subject_alt_name )
+ const mbedtls_x509_sequence
+ *subject_alt_name,
+ const char *prefix )
{
- size_t i;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const mbedtls_x509_sequence *cur = subject_alt_name;
- const char *sep = "";
- size_t sep_len = 0;
+ mbedtls_x509_subject_alternative_name san;
+ int parse_ret;
while( cur != NULL )
{
- if( cur->buf.len + sep_len >= n )
+ memset( &san, 0, sizeof( san ) );
+ parse_ret = mbedtls_x509_parse_subject_alt_name( &cur->buf, &san );
+ if( parse_ret != 0 )
{
- *p = '\0';
- return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ if( parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ else
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s <malformed>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ }
+ cur = cur->next;
+ continue;
}
- n -= cur->buf.len + sep_len;
- for( i = 0; i < sep_len; i++ )
- *p++ = sep[i];
- for( i = 0; i < cur->buf.len; i++ )
- *p++ = cur->buf.p[i];
+ switch( san.type )
+ {
+ /*
+ * otherName
+ */
+ case MBEDTLS_X509_SAN_OTHER_NAME:
+ {
+ mbedtls_x509_san_other_name *other_name = &san.san.other_name;
+
+ ret = mbedtls_snprintf( p, n, "\n%s otherName :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
- sep = ", ";
- sep_len = 2;
+ if( MBEDTLS_OID_CMP( MBEDTLS_OID_ON_HW_MODULE_NAME,
+ &other_name->value.hardware_module_name.oid ) != 0 )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s hardware module name :", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ ret = mbedtls_snprintf( p, n, "\n%s hardware type : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ ret = mbedtls_oid_get_numeric_string( p, n, &other_name->value.hardware_module_name.oid );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ ret = mbedtls_snprintf( p, n, "\n%s hardware serial number : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( other_name->value.hardware_module_name.val.len >= n )
+ {
+ *p = '\0';
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( p, other_name->value.hardware_module_name.val.p,
+ other_name->value.hardware_module_name.val.len );
+ p += other_name->value.hardware_module_name.val.len;
+
+ n -= other_name->value.hardware_module_name.val.len;
+
+ }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
+ }
+ break;
+
+ /*
+ * dNSName
+ */
+ case MBEDTLS_X509_SAN_DNS_NAME:
+ {
+ ret = mbedtls_snprintf( p, n, "\n%s dNSName : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ if( san.san.unstructured_name.len >= n )
+ {
+ *p = '\0';
+ return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
+ }
+
+ memcpy( p, san.san.unstructured_name.p, san.san.unstructured_name.len );
+ p += san.san.unstructured_name.len;
+ n -= san.san.unstructured_name.len;
+ }
+ break;
+
+ /*
+ * Type not supported, skip item.
+ */
+ default:
+ ret = mbedtls_snprintf( p, n, "\n%s <unsupported>", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+ break;
+ }
cur = cur->next;
}
@@ -1489,6 +1903,56 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
return( 0 );
}
+int mbedtls_x509_parse_subject_alt_name( const mbedtls_x509_buf *san_buf,
+ mbedtls_x509_subject_alternative_name *san )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ switch( san_buf->tag &
+ ( MBEDTLS_ASN1_TAG_CLASS_MASK |
+ MBEDTLS_ASN1_TAG_VALUE_MASK ) )
+ {
+ /*
+ * otherName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME ):
+ {
+ mbedtls_x509_san_other_name other_name;
+
+ ret = x509_get_other_name( san_buf, &other_name );
+ if( ret != 0 )
+ return( ret );
+
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_OTHER_NAME;
+ memcpy( &san->san.other_name,
+ &other_name, sizeof( other_name ) );
+
+ }
+ break;
+
+ /*
+ * dNSName
+ */
+ case( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME ):
+ {
+ memset( san, 0, sizeof( mbedtls_x509_subject_alternative_name ) );
+ san->type = MBEDTLS_X509_SAN_DNS_NAME;
+
+ memcpy( &san->san.unstructured_name,
+ san_buf, sizeof( *san_buf ) );
+
+ }
+ break;
+
+ /*
+ * Type not supported
+ */
+ default:
+ return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
+ }
+ return( 0 );
+}
+
#define PRINT_ITEM(i) \
{ \
ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
@@ -1503,7 +1967,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
static int x509_info_cert_type( char **buf, size_t *size,
unsigned char ns_cert_type )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const char *sep = "";
@@ -1530,7 +1994,7 @@ static int x509_info_cert_type( char **buf, size_t *size,
static int x509_info_key_usage( char **buf, size_t *size,
unsigned int key_usage )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n = *size;
char *p = *buf;
const char *sep = "";
@@ -1554,7 +2018,7 @@ static int x509_info_key_usage( char **buf, size_t *size,
static int x509_info_ext_key_usage( char **buf, size_t *size,
const mbedtls_x509_sequence *extended_key_usage )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const char *desc;
size_t n = *size;
char *p = *buf;
@@ -1580,6 +2044,35 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
return( 0 );
}
+static int x509_info_cert_policies( char **buf, size_t *size,
+ const mbedtls_x509_sequence *certificate_policies )
+{
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
+ const char *desc;
+ size_t n = *size;
+ char *p = *buf;
+ const mbedtls_x509_sequence *cur = certificate_policies;
+ const char *sep = "";
+
+ while( cur != NULL )
+ {
+ if( mbedtls_oid_get_certificate_policies( &cur->buf, &desc ) != 0 )
+ desc = "???";
+
+ ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ sep = ", ";
+
+ cur = cur->next;
+ }
+
+ *size = n;
+ *buf = p;
+
+ return( 0 );
+}
+
/*
* Return an informational string about the certificate.
*/
@@ -1588,7 +2081,7 @@ static int x509_info_ext_key_usage( char **buf, size_t *size,
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_crt *crt )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
char key_size_str[BEFORE_COLON];
@@ -1675,11 +2168,12 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
{
- ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
+ ret = mbedtls_snprintf( p, n, "\n%ssubject alt name :", prefix );
MBEDTLS_X509_SAFE_SNPRINTF;
if( ( ret = x509_info_subject_alt_name( &p, &n,
- &crt->subject_alt_names ) ) != 0 )
+ &crt->subject_alt_names,
+ prefix ) ) != 0 )
return( ret );
}
@@ -1711,6 +2205,16 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
return( ret );
}
+ if( crt->ext_types & MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES )
+ {
+ ret = mbedtls_snprintf( p, n, "\n%scertificate policies : ", prefix );
+ MBEDTLS_X509_SAFE_SNPRINTF;
+
+ if( ( ret = x509_info_cert_policies( &p, &n,
+ &crt->certificate_policies ) ) != 0 )
+ return( ret );
+ }
+
ret = mbedtls_snprintf( p, n, "\n" );
MBEDTLS_X509_SAFE_SNPRINTF;
@@ -1749,7 +2253,7 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
uint32_t flags )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const struct x509_crt_verify_string *cur;
char *p = buf;
size_t n = size;
@@ -1949,16 +2453,35 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
mbedtls_x509_crt *parent,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- const mbedtls_md_info_t *md_info;
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
-
+ size_t hash_len;
+#if !defined(MBEDTLS_USE_PSA_CRYPTO)
+ const mbedtls_md_info_t *md_info;
md_info = mbedtls_md_info_from_type( child->sig_md );
+ hash_len = mbedtls_md_get_size( md_info );
+
+ /* Note: hash errors can happen only after an internal error */
if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
+ return( -1 );
+#else
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( child->sig_md );
+
+ if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS )
+ return( -1 );
+
+ if( psa_hash_update( &hash_operation, child->tbs.p, child->tbs.len )
+ != PSA_SUCCESS )
{
- /* Note: this can't happen except after an internal error */
return( -1 );
}
+ if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len )
+ != PSA_SUCCESS )
+ {
+ return( -1 );
+ }
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Skip expensive computation on obvious mismatch */
if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) )
return( -1 );
@@ -1967,7 +2490,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA )
{
return( mbedtls_pk_verify_restartable( &parent->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
+ child->sig_md, hash, hash_len,
child->sig.p, child->sig.len, &rs_ctx->pk ) );
}
#else
@@ -1975,7 +2498,7 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child,
#endif
return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
- child->sig_md, hash, mbedtls_md_get_size( md_info ),
+ child->sig_md, hash, hash_len,
child->sig.p, child->sig.len ) );
}
@@ -2069,9 +2592,9 @@ static int x509_crt_find_parent_in(
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *parent, *fallback_parent;
- int signature_is_good, fallback_signature_is_good;
+ int signature_is_good = 0, fallback_signature_is_good;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* did we have something in progress? */
@@ -2192,7 +2715,7 @@ static int x509_crt_find_parent(
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_x509_crt *search_list;
*parent_is_trusted = 1;
@@ -2317,13 +2840,15 @@ static int x509_crt_verify_chain(
mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
mbedtls_x509_crt_verify_chain *ver_chain,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
/* Don't initialize any of those variables here, so that the compiler can
* catch potential issues with jumping ahead when restarting */
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
uint32_t *flags;
mbedtls_x509_crt_verify_chain_item *cur;
mbedtls_x509_crt *child;
@@ -2332,6 +2857,7 @@ static int x509_crt_verify_chain(
int child_is_trusted;
int signature_is_good;
unsigned self_cnt;
+ mbedtls_x509_crt *cur_trust_ca = NULL;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
/* resume if we had an operation in progress */
@@ -2391,8 +2917,32 @@ static int x509_crt_verify_chain(
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
find_parent:
#endif
+
+ /* Obtain list of potential trusted signers from CA callback,
+ * or use statically provided list. */
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ if( f_ca_cb != NULL )
+ {
+ mbedtls_x509_crt_free( ver_chain->trust_ca_cb_result );
+ mbedtls_free( ver_chain->trust_ca_cb_result );
+ ver_chain->trust_ca_cb_result = NULL;
+
+ ret = f_ca_cb( p_ca_cb, child, &ver_chain->trust_ca_cb_result );
+ if( ret != 0 )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ cur_trust_ca = ver_chain->trust_ca_cb_result;
+ }
+ else
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+ {
+ ((void) f_ca_cb);
+ ((void) p_ca_cb);
+ cur_trust_ca = trust_ca;
+ }
+
/* Look for a parent in trusted CAs or up the chain */
- ret = x509_crt_find_parent( child, trust_ca, &parent,
+ ret = x509_crt_find_parent( child, cur_trust_ca, &parent,
&parent_is_trusted, &signature_is_good,
ver_chain->len - 1, self_cnt, rs_ctx );
@@ -2481,6 +3031,25 @@ static int x509_crt_check_cn( const mbedtls_x509_buf *name,
}
/*
+ * Check for SAN match, see RFC 5280 Section 4.2.1.6
+ */
+static int x509_crt_check_san( const mbedtls_x509_buf *name,
+ const char *cn, size_t cn_len )
+{
+ const unsigned char san_type = (unsigned char) name->tag &
+ MBEDTLS_ASN1_TAG_VALUE_MASK;
+
+ /* dNSName */
+ if( san_type == MBEDTLS_X509_SAN_DNS_NAME )
+ return( x509_crt_check_cn( name, cn, cn_len ) );
+
+ /* (We may handle other types here later.) */
+
+ /* Unrecognized type */
+ return( -1 );
+}
+
+/*
* Verify the requested CN - only call this if cn is not NULL!
*/
static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
@@ -2495,7 +3064,7 @@ static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
{
for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
{
- if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 )
+ if( x509_crt_check_san( &cur->buf, cn, cn_len ) == 0 )
break;
}
@@ -2527,7 +3096,7 @@ static int x509_crt_merge_flags_with_cb(
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned i;
uint32_t cur_flags;
const mbedtls_x509_crt_verify_chain_item *cur;
@@ -2548,36 +3117,6 @@ static int x509_crt_merge_flags_with_cb(
}
/*
- * Verify the certificate validity (default profile, not restartable)
- */
-int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
-{
- return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
- &mbedtls_x509_crt_profile_default, cn, flags,
- f_vrfy, p_vrfy, NULL ) );
-}
-
-/*
- * Verify the certificate validity (user-chosen profile, not restartable)
- */
-int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
- mbedtls_x509_crt *trust_ca,
- mbedtls_x509_crl *ca_crl,
- const mbedtls_x509_crt_profile *profile,
- const char *cn, uint32_t *flags,
- int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
- void *p_vrfy )
-{
- return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
- profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
-}
-
-/*
* Verify the certificate validity, with profile, restartable version
*
* This function:
@@ -2586,17 +3125,26 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
* as that isn't done as part of chain building/verification currently
* - builds and verifies the chain
* - then calls the callback and merges the flags
+ *
+ * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb`
+ * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the
+ * verification routine to search for trusted signers, and CRLs will
+ * be disabled. Otherwise, `trust_ca` will be used as the static list
+ * of trusted signers, and `ca_crl` will be use as the static list
+ * of CRLs.
*/
-int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+static int x509_crt_verify_restartable_ca_cb( mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
mbedtls_pk_type_t pk_type;
mbedtls_x509_crt_verify_chain ver_chain;
uint32_t ee_flags;
@@ -2625,7 +3173,8 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
/* Check the chain */
- ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
+ ret = x509_crt_verify_chain( crt, trust_ca, ca_crl,
+ f_ca_cb, p_ca_cb, profile,
&ver_chain, rs_ctx );
if( ret != 0 )
@@ -2638,6 +3187,13 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
exit:
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+ mbedtls_x509_crt_free( ver_chain.trust_ca_cb_result );
+ mbedtls_free( ver_chain.trust_ca_cb_result );
+ ver_chain.trust_ca_cb_result = NULL;
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
mbedtls_x509_crt_restart_free( rs_ctx );
@@ -2661,6 +3217,77 @@ exit:
return( 0 );
}
+
+/*
+ * Verify the certificate validity (default profile, not restartable)
+ */
+int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ &mbedtls_x509_crt_profile_default,
+ cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+
+/*
+ * Verify the certificate validity (user-chosen profile, not restartable)
+ */
+int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+
+#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
+/*
+ * Verify the certificate validity (user-chosen profile, CA callback,
+ * not restartable).
+ */
+int mbedtls_x509_crt_verify_with_ca_cb( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt_ca_cb_t f_ca_cb,
+ void *p_ca_cb,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, NULL, NULL,
+ f_ca_cb, p_ca_cb,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, NULL ) );
+}
+#endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
+
+int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt,
+ mbedtls_x509_crt *trust_ca,
+ mbedtls_x509_crl *ca_crl,
+ const mbedtls_x509_crt_profile *profile,
+ const char *cn, uint32_t *flags,
+ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
+ void *p_vrfy,
+ mbedtls_x509_crt_restart_ctx *rs_ctx )
+{
+ return( x509_crt_verify_restartable_ca_cb( crt, trust_ca, ca_crl,
+ NULL, NULL,
+ profile, cn, flags,
+ f_vrfy, p_vrfy, rs_ctx ) );
+}
+
+
/*
* Initialize a certificate chain
*/
@@ -2730,7 +3357,17 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
mbedtls_free( seq_prv );
}
- if( cert_cur->raw.p != NULL )
+ seq_cur = cert_cur->certificate_policies.next;
+ while( seq_cur != NULL )
+ {
+ seq_prv = seq_cur;
+ seq_cur = seq_cur->next;
+ mbedtls_platform_zeroize( seq_prv,
+ sizeof( mbedtls_x509_sequence ) );
+ mbedtls_free( seq_prv );
+ }
+
+ if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
{
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
mbedtls_free( cert_cur->raw.p );
diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c
index 663047d516..e259410d07 100644
--- a/thirdparty/mbedtls/library/x509_csr.c
+++ b/thirdparty/mbedtls/library/x509_csr.c
@@ -2,13 +2,7 @@
* X.509 Certificate Signing Request (CSR) parsing
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* The ITU-T X.509 standard defines a certificate format for PKI.
@@ -54,15 +27,12 @@
* http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CSR_PARSE_C)
#include "mbedtls/x509_csr.h"
+#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
@@ -93,7 +63,7 @@ static int x509_csr_get_version( unsigned char **p,
const unsigned char *end,
int *ver )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
{
@@ -103,7 +73,7 @@ static int x509_csr_get_version( unsigned char **p,
return( 0 );
}
- return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
}
return( 0 );
@@ -115,7 +85,7 @@ static int x509_csr_get_version( unsigned char **p,
int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
const unsigned char *buf, size_t buflen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len;
unsigned char *p, *end;
mbedtls_x509_buf sig_params;
@@ -161,8 +131,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
if( len != (size_t) ( end - p ) )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
/*
@@ -174,7 +144,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
end = p + len;
@@ -206,7 +176,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
@@ -240,7 +210,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
}
p += len;
@@ -274,8 +244,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
if( p != end )
{
mbedtls_x509_csr_free( csr );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
+ return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
+ MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
}
return( 0 );
@@ -287,7 +257,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t use_len;
mbedtls_pem_context pem;
#endif
@@ -337,7 +307,7 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz
*/
int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
unsigned char *buf;
@@ -361,7 +331,7 @@ int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_csr *csr )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t n;
char *p;
char key_size_str[BEFORE_COLON];
diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c
index aaffd14c86..184c90cd33 100644
--- a/thirdparty/mbedtls/library/x509write_crt.c
+++ b/thirdparty/mbedtls/library/x509write_crt.c
@@ -2,13 +2,7 @@
* X.509 certificate writing
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* References:
@@ -50,19 +23,16 @@
* - attributes: PKCS#9 v2.0 aka RFC 2985
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CRT_WRITE_C)
#include "mbedtls/x509_crt.h"
-#include "mbedtls/oid.h"
#include "mbedtls/asn1write.h"
-#include "mbedtls/sha1.h"
+#include "mbedtls/error.h"
+#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#include "mbedtls/sha1.h"
#include <string.h>
@@ -70,16 +40,6 @@
#include "mbedtls/pem.h"
#endif /* MBEDTLS_PEM_WRITE_C */
-/*
- * For the currently used signature algorithms the buffer to store any signature
- * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
- */
-#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
-#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
-#else
-#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
-#endif
-
void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
{
memset( ctx, 0, sizeof( mbedtls_x509write_cert ) );
@@ -138,7 +98,7 @@ int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx,
const mbedtls_mpi *serial )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
return( ret );
@@ -175,7 +135,7 @@ int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
int is_ca, int max_pathlen )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[9];
unsigned char *c = buf + sizeof(buf);
size_t len = 0;
@@ -209,7 +169,7 @@ int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
#if defined(MBEDTLS_SHA1_C)
int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
unsigned char *c = buf + sizeof(buf);
size_t len = 0;
@@ -237,7 +197,7 @@ int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ct
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
unsigned char *c = buf + sizeof( buf );
size_t len = 0;
@@ -270,46 +230,33 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *
}
#endif /* MBEDTLS_SHA1_C */
-static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring,
- size_t bit_offset )
-{
- size_t unused_bits;
-
- /* Count the unused bits removing trailing 0s */
- for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
- if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
- break;
-
- return( unused_bits );
-}
-
int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
unsigned int key_usage )
{
- unsigned char buf[4], ku;
+ unsigned char buf[5] = {0}, ku[2] = {0};
unsigned char *c;
- int ret;
- size_t unused_bits;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE |
MBEDTLS_X509_KU_NON_REPUDIATION |
MBEDTLS_X509_KU_KEY_ENCIPHERMENT |
MBEDTLS_X509_KU_DATA_ENCIPHERMENT |
MBEDTLS_X509_KU_KEY_AGREEMENT |
MBEDTLS_X509_KU_KEY_CERT_SIGN |
- MBEDTLS_X509_KU_CRL_SIGN;
+ MBEDTLS_X509_KU_CRL_SIGN |
+ MBEDTLS_X509_KU_ENCIPHER_ONLY |
+ MBEDTLS_X509_KU_DECIPHER_ONLY;
/* Check that nothing other than the allowed flags is set */
if( ( key_usage & ~allowed_bits ) != 0 )
return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
- c = buf + 4;
- ku = (unsigned char)key_usage;
- unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 );
- ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits );
+ c = buf + 5;
+ MBEDTLS_PUT_UINT16_LE( key_usage, ku, 0 );
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 );
if( ret < 0 )
return( ret );
- else if( ret < 3 || ret > 4 )
+ else if( ret < 3 || ret > 5 )
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
@@ -324,18 +271,13 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
unsigned char ns_cert_type )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
- ret = mbedtls_asn1_write_bitstring( &c,
- buf,
- &ns_cert_type,
- 8 - unused_bits );
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 );
if( ret < 3 || ret > 4 )
return( ret );
@@ -351,7 +293,7 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
static int x509_write_time( unsigned char **p, unsigned char *start,
const char *t, size_t size )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t len = 0;
/*
@@ -384,12 +326,12 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
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 sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE];
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;
@@ -578,7 +520,7 @@ int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen;
if( ( ret = mbedtls_x509write_crt_der( crt, buf, size,
diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c
index 60cf12379f..afda950341 100644
--- a/thirdparty/mbedtls/library/x509write_csr.c
+++ b/thirdparty/mbedtls/library/x509write_csr.c
@@ -2,13 +2,7 @@
* X.509 Certificate Signing Request writing
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,27 +15,6 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
/*
* References:
@@ -49,19 +22,21 @@
* - attributes: PKCS#9 v2.0 aka RFC 2985
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_X509_CSR_WRITE_C)
#include "mbedtls/x509_csr.h"
-#include "mbedtls/oid.h"
#include "mbedtls/asn1write.h"
+#include "mbedtls/error.h"
+#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+#include "psa/crypto.h"
+#include "mbedtls/psa_util.h"
+#endif
+
#include <string.h>
#include <stdlib.h>
@@ -69,16 +44,6 @@
#include "mbedtls/pem.h"
#endif
-/*
- * For the currently used signature algorithms the buffer to store any signature
- * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
- */
-#if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
-#define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
-#else
-#define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
-#endif
-
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -124,35 +89,17 @@ int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
0, val, val_len );
}
-static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
- size_t bit_offset )
-{
- size_t unused_bits;
-
- /* Count the unused bits removing trailing 0s */
- for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
- if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
- break;
-
- return( unused_bits );
-}
-
int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
- ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
-
- if( ret < 0 )
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &key_usage, 8 );
+ if( ret < 3 || ret > 4 )
return( ret );
- else if( ret < 3 || ret > 4 )
- return( MBEDTLS_ERR_X509_INVALID_FORMAT );
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
@@ -166,22 +113,14 @@ int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned ch
int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
unsigned char ns_cert_type )
{
- unsigned char buf[4];
+ unsigned char buf[4] = {0};
unsigned char *c;
- size_t unused_bits;
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
c = buf + 4;
- unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
- ret = mbedtls_asn1_write_bitstring( &c,
- buf,
- &ns_cert_type,
- 8 - unused_bits );
-
- if( ret < 0 )
- return( ret );
- else if( ret < 3 || ret > 4 )
+ ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 );
+ if( ret < 3 || ret > 4 )
return( ret );
ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
@@ -200,7 +139,7 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const char *sig_oid;
size_t sig_oid_len = 0;
unsigned char *c, *c2;
@@ -208,6 +147,11 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
size_t len = 0;
mbedtls_pk_type_t pk_alg;
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ psa_hash_operation_t hash_operation = PSA_HASH_OPERATION_INIT;
+ size_t hash_len;
+ psa_algorithm_t hash_alg = mbedtls_psa_translate_md( ctx->md_alg );
+#endif /* MBEDTLS_USE_PSA_CRYPTO */
/* Write the CSR backwards starting from the end of buf */
c = buf + size;
@@ -273,10 +217,23 @@ static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx,
* Sign the written CSR data into the sig buffer
* Note: hash errors can happen only after an internal error
*/
+#if defined(MBEDTLS_USE_PSA_CRYPTO)
+ if( psa_hash_setup( &hash_operation, hash_alg ) != PSA_SUCCESS )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ if( psa_hash_update( &hash_operation, c, len ) != PSA_SUCCESS )
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+
+ if( psa_hash_finish( &hash_operation, hash, sizeof( hash ), &hash_len )
+ != PSA_SUCCESS )
+ {
+ return( MBEDTLS_ERR_X509_FATAL_ERROR );
+ }
+#else /* MBEDTLS_USE_PSA_CRYPTO */
ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
if( ret != 0 )
return( ret );
-
+#endif
if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
f_rng, p_rng ) ) != 0 )
{
@@ -341,7 +298,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf,
int ret;
unsigned char *sig;
- if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL )
+ if( ( sig = mbedtls_calloc( 1, MBEDTLS_PK_SIGNATURE_MAX_SIZE ) ) == NULL )
{
return( MBEDTLS_ERR_X509_ALLOC_FAILED );
}
@@ -361,18 +318,17 @@ int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, s
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
- int ret;
- unsigned char output_buf[4096];
+ int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen = 0;
- if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
+ if( ( ret = mbedtls_x509write_csr_der( ctx, buf, size,
f_rng, p_rng ) ) < 0 )
{
return( ret );
}
if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
- output_buf + sizeof(output_buf) - ret,
+ buf + size - ret,
ret, buf, size, &olen ) ) != 0 )
{
return( ret );
diff --git a/thirdparty/mbedtls/library/xtea.c b/thirdparty/mbedtls/library/xtea.c
index 4e62817579..77f6cb6f67 100644
--- a/thirdparty/mbedtls/library/xtea.c
+++ b/thirdparty/mbedtls/library/xtea.c
@@ -2,13 +2,7 @@
* An 32-bit implementation of the XTEA algorithm
*
* 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
- * GNU General Public License v2.0 or later.
- *
- * **********
- * Apache License 2.0:
+ * SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
@@ -21,34 +15,9 @@
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- * **********
- *
- * **********
- * GNU General Public License v2.0 or later:
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * **********
*/
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "mbedtls/config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "common.h"
#if defined(MBEDTLS_XTEA_C)
@@ -68,29 +37,6 @@
#if !defined(MBEDTLS_XTEA_ALT)
-/*
- * 32-bit integer manipulation macros (big endian)
- */
-#ifndef GET_UINT32_BE
-#define GET_UINT32_BE(n,b,i) \
-{ \
- (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
- | ( (uint32_t) (b)[(i) + 1] << 16 ) \
- | ( (uint32_t) (b)[(i) + 2] << 8 ) \
- | ( (uint32_t) (b)[(i) + 3] ); \
-}
-#endif
-
-#ifndef PUT_UINT32_BE
-#define PUT_UINT32_BE(n,b,i) \
-{ \
- (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
- (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
- (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
- (b)[(i) + 3] = (unsigned char) ( (n) ); \
-}
-#endif
-
void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
@@ -115,7 +61,7 @@ void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16]
for( i = 0; i < 4; i++ )
{
- GET_UINT32_BE( ctx->k[i], key, i << 2 );
+ ctx->k[i] = MBEDTLS_GET_UINT32_BE( key, i << 2 );
}
}
@@ -129,8 +75,8 @@ int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
k = ctx->k;
- GET_UINT32_BE( v0, input, 0 );
- GET_UINT32_BE( v1, input, 4 );
+ v0 = MBEDTLS_GET_UINT32_BE( input, 0 );
+ v1 = MBEDTLS_GET_UINT32_BE( input, 4 );
if( mode == MBEDTLS_XTEA_ENCRYPT )
{
@@ -155,8 +101,8 @@ int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
}
}
- PUT_UINT32_BE( v0, output, 0 );
- PUT_UINT32_BE( v1, output, 4 );
+ MBEDTLS_PUT_UINT32_BE( v0, output, 0 );
+ MBEDTLS_PUT_UINT32_BE( v1, output, 4 );
return( 0 );
}
diff --git a/thirdparty/mbedtls/patches/padlock.diff b/thirdparty/mbedtls/patches/padlock.diff
deleted file mode 100644
index 6ace48891c..0000000000
--- a/thirdparty/mbedtls/patches/padlock.diff
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/thirdparty/mbedtls/include/mbedtls/config.h
-+++ b/thirdparty/mbedtls/include/mbedtls/config.h
-@@ -2477,7 +2477,9 @@
- *
- * This modules adds support for the VIA PadLock on x86.
- */
--#define MBEDTLS_PADLOCK_C
-+// -- GODOT start --
-+// #define MBEDTLS_PADLOCK_C
-+// -- GODOT end --
-
- /**
- * \def MBEDTLS_PEM_PARSE_C